]> git.sesse.net Git - ultimatescore/blob - score.js
Make a more neutral start image.
[ultimatescore] / score.js
1 'use strict';
2
3 let clock_running = false;
4 let clock_visible = false;
5 let comment_visible = false;
6 let lowerthird_visible = false;
7 let clock_elapsed = 0;
8 let clock_limit = 30 * 60;
9 let scoreA = 0;
10 let scoreB = 0;
11 let clock_origin;
12 let state = {};
13
14 function setteams()
15 {
16         document.getElementById('team1').innerHTML = state['team1'];
17         document.getElementById('team2').innerHTML = state['team2'];
18
19         let sheets = { 'A': state['team1'], 'B': state['team2'] };
20         loadquickl3s(sheets);
21 }
22
23 function setcolors()
24 {
25         document.getElementById('team1color').style.backgroundColor = state['team1color'];
26         document.getElementById('team2color').style.backgroundColor = state['team2color'];
27 }
28
29 function setscore()
30 {
31         scoreA = state['score1'];
32         scoreB = state['score2'];
33         update_score();
34 }
35
36 function startclock()
37 {
38         if (!clock_running) {
39                 clock_origin = Date.now();
40                 clock_running = true;
41         }
42         showclock();
43 }
44
45 function stopclock()
46 {
47         if (!clock_running) return;
48         clock_elapsed = time_elapsed();
49         clock_origin = Date.now();
50         clock_running = false;
51 }
52
53 function setclock(amount)
54 {
55         clock_elapsed = amount;
56         clock_origin = Date.now();
57         update_clock();
58 }
59
60 function setclockfromstate()
61 {
62         let amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
63         setclock(amount);
64 }
65
66 function adjustclockfromstate()
67 {
68         let amount = parseInt(state['clock_min']) * 60 + parseInt(state['clock_sec']);
69         let elapsed = time_elapsed_raw();
70         if (Math.abs(amount - elapsed) >= 2.0) {
71                 setclock(amount);
72         }
73 }
74
75 function setclocklimitfromstate()
76 {
77         let amount = parseInt(state['clock_limit_min']) * 60 + parseInt(state['clock_limit_sec']);
78         clock_limit = amount;
79 }
80
81 function showclock()
82 {
83         if (clock_visible) return;
84         let clockbug = document.getElementById('clockbug');
85         clockbug.className = 'clockbug clockbug-animate-in';
86         clock_visible = true;
87 }
88
89 function hideclock()
90 {
91         if (!clock_visible) return;
92         let clockbug = document.getElementById('clockbug');
93         clockbug.className = 'clockbug clockbug-animate-out';
94         clock_visible = false;
95 }
96
97 function setcomment()
98 {
99         document.getElementById('comment').innerHTML = state['comment'];
100 }
101
102 function showcomment()
103 {
104         if (comment_visible) return;
105         let commentbug = document.getElementById('commentbug');
106         commentbug.className = 'commentbug commentbug-animate-in';
107         comment_visible = true;
108 }
109
110 function hidecomment()
111 {
112         if (!comment_visible) return;
113         let commentbug = document.getElementById('commentbug');
114         commentbug.className = 'commentbug commentbug-animate-out';
115         comment_visible = false;
116 }
117
118 function showlowerthird()
119 {
120         if (lowerthird_visible) return;
121
122         document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-animate-in';
123         document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-in';
124         document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-in';
125         document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-in';
126         document.getElementById('lowerthird-picture').className = 'lowerthird-picture lowerthird-picture-animate-in';
127         document.getElementById('lowerthird-picture-content').className = 'lowerthird-picture-content lowerthird-picture-content-animate-in';
128         lowerthird_visible = true;
129 }
130
131 function setandshowlowerthird()
132 {
133         document.getElementById('lowerthird-headline-content').innerHTML = state['text1'];
134         document.getElementById('lowerthird-subheading-content').innerHTML = state['text2'];
135         let img = document.getElementById('lowerthird-img');
136         if (state['image'] === undefined) {
137                 img.style.display = 'none';
138         } else {
139                 img.src = state['image'];       
140                 img.style.display = 'inline';
141         }
142         showlowerthird();
143 }
144
145 function hidelowerthird()
146 {
147         if (!lowerthird_visible) return;
148         document.getElementById('lowerthird-headline').className = 'lowerthird-headline lowerthird-headline-hidden lowerthird-headline-animate-out';
149         document.getElementById('lowerthird-headline-content').className = 'lowerthird-headline-content lowerthird-headline-content-animate-out';
150         document.getElementById('lowerthird-subheading').className = 'lowerthird-subheading lowerthird-subheading-animate-out';
151         document.getElementById('lowerthird-subheading-content').className = 'lowerthird-subheading-content lowerthird-subheading-content-animate-out';
152         document.getElementById('lowerthird-picture').className = 'lowerthird-picture lowerthird-picture-animate-out';
153         document.getElementById('lowerthird-picture-content').className = 'lowerthird-picture-content lowerthird-picture-content-animate-out';
154         lowerthird_visible = false;
155 }
156
157 function time_elapsed_raw()
158 {
159         let elapsed = (Date.now() - clock_origin) * 1e-3;
160         if (clock_elapsed + elapsed >= clock_limit) {
161                 clock_elapsed = clock_limit;
162                 clock_origin = Date.now();
163                 clock_running = false;
164                 return clock_limit;
165         }
166         return clock_elapsed + elapsed;
167 }
168
169 function time_elapsed()
170 {
171         return Math.floor(time_elapsed_raw());
172 }
173
174 function update_clock()
175 {
176         let elapsed = time_elapsed();
177         let min = Math.floor(elapsed / 60);
178         let sec = elapsed % 60;
179
180         if (sec < 10) sec = "0" + sec;
181         let text = min + ":" + sec;
182
183         if (false) {
184                 // This is a hack around the fact that Exo has variable-width numerals.
185                 // It doesn't look fantastic, but for the clock, it's better not to have
186                 // the text jumping around.
187                 let html = "";
188                 for (let i = 0; i < text.length; ++i) {
189                         if (text.charAt(i) === ':') {
190                                 html += ':';
191                         } else {
192                                 html += "<div style='display: inline-block; width: 15px'>" + text.charAt(i) + "</div>";
193                         }
194                 }
195                 document.getElementById('clock').innerHTML = html;
196         } else {
197                 document.getElementById('clock').innerHTML = text;
198         }
199 }
200
201 function goalA()
202 {
203         ++scoreA;
204         update_score();
205 }
206
207 function goalB()
208 {
209         ++scoreB;
210         update_score();
211 }
212
213 function ungoalA()
214 {
215         if (scoreA > 0) --scoreA;
216         update_score();
217 }
218
219 function ungoalB()
220 {
221         if (scoreB > 0) --scoreB;
222         update_score();
223 }
224
225 function resetscore()
226 {
227         scoreA = scoreB = 0;
228         update_score();
229 }
230
231 function update_score()
232 {
233         document.getElementById('score').innerHTML = scoreA + "&nbsp;–&nbsp;" + scoreB;
234 }
235
236 /* called by the Nageru theme only */
237 function play()
238 {
239         document.getElementById('manualcontrols').style.display = 'none';
240         document.getElementById('area').style.display = 'none';
241 }
242
243 function update(v)
244 {
245         console.log('[[[' + v + ']]]');
246         let j = JSON.parse(v);
247         for(let key in j) state[key] = j[key];
248 }
249
250 setInterval(function() {
251         if (clock_running) {
252                 update_clock();
253         }
254 }, 100);
255 update_score();
256
257 //play();
258 //startclock();
259
260 let websocket = null;
261
262 function open_ws()
263 {
264         console.log("Connecting...");
265         try {
266                 if (websocket)
267                         websocket.close();
268                 websocket = new WebSocket("ws://127.0.0.1:5250/");
269                 websocket.onopen = function(evt) {
270                         console.log("Connected to client.");
271                 };
272                 websocket.onclose = function(evt) {
273                         console.log("Disconnected from client.");
274                         setTimeout(open_ws, 100);
275                 };
276                 websocket.onmessage = function(evt) {
277                         let msg = evt.data;
278                         let m = msg.match(/^update (.*)/);
279                         if (m !== null) {
280                                 update(m[1]);
281                         }
282                         m = msg.match(/^eval (.*)/);
283                         if (m !== null) {
284                                 eval(m[1]);
285                         }
286                 };
287                 websocket.onerror = function(evt) {
288                         console.log('Error: ' + evt.data);
289                 };
290         } catch (exception) {
291                 console.log('Error: ' + exception);
292                 setTimeout(open_ws, 100);
293         }
294 };
295 open_ws();