Commit | Line | Data |
---|---|---|
72b294bb | 1 | "use strict"; |
2 | ||
3 | function Timer(id) { | |
4 | var precision = 100; // milliseconds | |
5 | var defaultTime = (15 * 60 + 0) * 1000; // milliseconds | |
6 | var time = defaultTime; | |
7 | var intervalID; | |
8 | this.isTicking = false; | |
59026107 AIL |
9 | var increment = 0; |
10 | var defaultIncrement = 0; | |
11 | ||
72b294bb | 12 | var outputTime = function() { |
13 | document.getElementById(id).innerHTML = timeToTimeStr(time); | |
14 | var flagid = "flag-" + id.split('-')[1]; | |
15 | var flagelem = document.getElementById(flagid); | |
16 | flagelem.style.visibility = time <= 0 ? "visible" : "hidden"; | |
59026107 AIL |
17 | var incid = "increment-" + id.split('-')[1]; |
18 | var incelem = document.getElementById(incid); | |
19 | incelem.innerHTML = "+" + (increment / 1000).toString(); | |
20 | incelem.style.visibility = increment > 0 ? "visible" : "hidden"; | |
72b294bb | 21 | }; |
6f474901 AIL |
22 | |
23 | var startTickingUnixTime = null; | |
24 | var remainingTimeAtTickingStart = null; | |
25 | ||
72b294bb | 26 | var thisTimer = this; // workaround to use this in setInterval |
27 | this.tick = function() { | |
6f474901 AIL |
28 | var currentPassedTime = new Date() - startTickingUnixTime; |
29 | time = remainingTimeAtTickingStart - currentPassedTime; | |
72b294bb | 30 | if(time <= 0) { |
6f474901 | 31 | time = 0; |
72b294bb | 32 | // time's up |
33 | clearInterval(intervalID); | |
34 | thisTimer.isTicking = false; | |
35 | } | |
36 | outputTime(); | |
37 | }; | |
38 | this.start = function() { | |
6f474901 AIL |
39 | startTickingUnixTime = new Date(); |
40 | remainingTimeAtTickingStart = time; | |
72b294bb | 41 | intervalID = setInterval(this.tick, precision); |
42 | this.isTicking = true; | |
43 | }; | |
59026107 | 44 | this.stop = function(toggle = false) { |
72b294bb | 45 | clearInterval(intervalID); |
46 | this.isTicking = false; | |
59026107 AIL |
47 | if (toggle && this.getTime() > 0) { |
48 | this.setTime(this.getTime() + increment, increment, true); | |
49 | } | |
72b294bb | 50 | }; |
59026107 | 51 | this.setTime = function(t, inc = 0, toggle = false) { |
72b294bb | 52 | time = t; |
59026107 AIL |
53 | increment = inc; |
54 | if (!toggle) { | |
55 | defaultTime = t; | |
56 | defaultIncrement = inc; | |
57 | } | |
72b294bb | 58 | outputTime(); |
59 | }; | |
60 | this.getTime = function() { | |
61 | return time; | |
62 | }; | |
63 | this.reset = function() { | |
64 | if(this.isTicking) { | |
65 | this.stop(); | |
66 | } | |
59026107 | 67 | this.setTime(defaultTime, defaultIncrement); |
72b294bb | 68 | }; |
69 | this.getDefaultTime = function() { | |
70 | return defaultTime; | |
71 | }; | |
72 | } | |
73 | ||
74 | var currentTimers = new (function() { | |
75 | this.leftTimer = new Timer("timer-left"); | |
76 | this.rightTimer = new Timer("timer-right"); | |
77 | this.active = this.leftTimer; | |
78 | this.passive = this.rightTimer; | |
79 | this.isPaused = true; | |
80 | this.swap = function() { | |
81 | var tmp = this.passive; | |
82 | this.passive = this.active; | |
83 | this.active = tmp; | |
84 | var icon = document.getElementById("play"); | |
59026107 | 85 | icon.innerHTML = (icon.innerHTML == "⏴" ? "⏵" : "⏴"); |
72b294bb | 86 | }; |
87 | this.pause = function() { | |
88 | this.active.stop(); | |
89 | this.isPaused = true; | |
90 | document.getElementById("pause").style.visibility = "visible"; | |
91 | }; | |
92 | this.resume = function() { | |
93 | this.active.start(); | |
94 | this.isPaused = false; | |
95 | document.getElementById("pause").style.visibility = "hidden"; | |
96 | }; | |
97 | })(); | |
98 | ||
99 | function timeStrToTime(timeStr) { | |
100 | var minute = parseInt(timeStr.substr(0, 2)); | |
101 | var second = parseInt(timeStr.substr(3, 2)); | |
102 | return (minute * 60 + second) * 1000; | |
103 | } | |
104 | ||
105 | function timeToTimeStr(time) { | |
106 | var minute = Math.floor(time / 1000 / 60); | |
107 | var second = Math.floor(time / 1000) % 60; | |
108 | if(minute < 10) { | |
109 | minute = '0' + minute.toString(); | |
110 | } | |
111 | if(second < 10) { | |
112 | second = '0' + second.toString(); | |
113 | } | |
114 | return minute + ':' + second; | |
115 | } | |
116 | ||
117 | document.onkeydown = function(e) { | |
118 | if(e.key) { | |
119 | switch(e.key) { | |
120 | case ' ': return toggle(); | |
121 | case 'S': | |
122 | case 's': return setTime(); | |
123 | case 'R': | |
124 | case 'r': return reset(); | |
125 | case 'p': | |
126 | case 'P': return pauseResume(); | |
127 | default: return; | |
128 | } | |
129 | } else if(e.keyCode) { | |
130 | switch(e.keyCode) { | |
131 | case 32: return toggle(); // space | |
132 | case 83: return setTime(); // S | |
133 | case 82: return reset(); // R | |
134 | case 80: return pauseResume(); // P | |
135 | default: return; | |
136 | } | |
137 | } else { | |
138 | alert("Browser not supported"); | |
139 | } | |
140 | }; | |
141 | ||
142 | function toggle() { | |
143 | if(!currentTimers.isPaused) { | |
59026107 | 144 | currentTimers.active.stop(true); |
72b294bb | 145 | currentTimers.passive.start(); |
146 | } | |
147 | currentTimers.swap(); | |
148 | var lbt = document.getElementById('left-button-top'); | |
149 | var leftIsLong = lbt.getAttribute('class') == 'button-long'; | |
150 | var lbt_d = lbt.getAttribute('d').split(' '); | |
151 | var lbb = document.getElementById('left-button-body'); | |
152 | var rbt = document.getElementById('right-button-top'); | |
153 | var rbt_d = rbt.getAttribute('d').split(' '); | |
154 | var rbb = document.getElementById('right-button-body'); | |
6f474901 | 155 | |
72b294bb | 156 | var y_diff = 50 * (leftIsLong ? 1 : -1); |
157 | var classes = ['button-short', 'button-long']; | |
158 | ||
159 | lbt_d[2] = (parseInt(lbt_d[2]) + y_diff).toString(); | |
160 | lbt_d[10] = (parseInt(lbt_d[10]) + y_diff).toString(); | |
161 | lbb.setAttribute('height', | |
162 | (parseInt(lbb.getAttribute('height')) - y_diff).toString()); | |
163 | lbb.setAttribute('y', (parseInt(lbb.getAttribute('y')) + y_diff).toString()); | |
164 | rbt_d[2] = (parseInt(rbt_d[2]) - y_diff).toString(); | |
165 | rbt_d[10] = (parseInt(rbt_d[10]) - y_diff).toString(); | |
166 | rbb.setAttribute('height', | |
167 | (parseInt(rbb.getAttribute('height')) + y_diff).toString()); | |
168 | rbb.setAttribute('y', (parseInt(rbb.getAttribute('y')) - y_diff).toString()); | |
169 | lbt.setAttribute('class', classes[(leftIsLong + 1) % 2]); | |
170 | lbb.setAttribute('class', classes[(leftIsLong + 1) % 2]); | |
171 | rbt.setAttribute('class', classes[(leftIsLong + 1) % 2]); | |
172 | rbb.setAttribute('class', classes[(leftIsLong + 1) % 2]); | |
173 | lbt.setAttribute('d', lbt_d.join(' ')); | |
174 | rbt.setAttribute('d', rbt_d.join(' ')); | |
6f474901 | 175 | |
72b294bb | 176 | lbt.setAttribute('onclick', leftIsLong ? '' : 'toggle()'); |
177 | lbb.setAttribute('onclick', leftIsLong ? '' : 'toggle()'); | |
178 | lbt.setAttribute('cursor', leftIsLong ? 'default' : 'pointer'); | |
179 | lbb.setAttribute('cursor', leftIsLong ? 'default' : 'pointer'); | |
180 | rbt.setAttribute('onclick', leftIsLong ? 'toggle()' : ''); | |
181 | rbb.setAttribute('onclick', leftIsLong ? 'toggle()' : ''); | |
182 | rbt.setAttribute('cursor', leftIsLong ? 'pointer' : 'default'); | |
183 | rbb.setAttribute('cursor', leftIsLong ? 'pointer' : 'default'); | |
184 | } | |
185 | ||
186 | function pauseResume() { | |
187 | if(currentTimers.isPaused) { | |
188 | currentTimers.resume(); | |
189 | } else { | |
190 | currentTimers.pause(); | |
191 | } | |
192 | } | |
193 | ||
194 | function setTime() { | |
195 | var leftstart, rightstart; | |
196 | var def = timeToTimeStr(currentTimers.leftTimer.getDefaultTime()); | |
59026107 | 197 | var regex = /[0-9][0-9]:[0-5][0-9](\+[0-9]+)?/; |
6f474901 | 198 | |
59026107 | 199 | leftstart = prompt("Time for LEFT player in MM:SS or MM:SS+S", def); |
72b294bb | 200 | if(leftstart === null) return; // Cancel |
201 | while(!leftstart.match(regex)) { | |
59026107 | 202 | leftstart = prompt("Invalid value\nTime for LEFT player in MM:SS or MM:SS+S", def); |
72b294bb | 203 | if(leftstart === null) return; // Cancel |
204 | } | |
205 | def = leftstart; | |
59026107 | 206 | rightstart = prompt("Time for RIGHT player in MM:SS or MM:SS+S", def); |
72b294bb | 207 | if(rightstart === null) return; // Cancel |
208 | while(!rightstart.match(regex)) { | |
59026107 | 209 | rightstart = prompt("Invalid value\nTime for RIGHT player in MM:SS or MM:SS+S", def); |
72b294bb | 210 | if(rightstart === null) return; // Cancel |
211 | } | |
59026107 AIL |
212 | |
213 | if(leftstart.indexOf('+') > 0) { | |
214 | var baseTime = leftstart.split('+')[0]; | |
215 | var inc = leftstart.split('+')[1]; | |
216 | currentTimers.leftTimer.setTime(timeStrToTime(baseTime), parseInt(inc) * 1000); | |
217 | } | |
218 | else { | |
219 | currentTimers.leftTimer.setTime(timeStrToTime(leftstart)); | |
220 | } | |
221 | if(rightstart.indexOf('+') > 0) { | |
222 | var baseTime = rightstart.split('+')[0]; | |
223 | var inc = rightstart.split('+')[1]; | |
224 | currentTimers.rightTimer.setTime(timeStrToTime(baseTime), parseInt(inc) * 1000); | |
225 | } | |
226 | else { | |
227 | currentTimers.rightTimer.setTime(timeStrToTime(leftstart)); | |
228 | } | |
72b294bb | 229 | } |
230 | ||
231 | function reset() { | |
232 | currentTimers.pause(); | |
233 | currentTimers.active.reset(); | |
234 | currentTimers.passive.reset(); | |
235 | } | |
236 | ||
237 | function init() { | |
238 | insertcss(); | |
6f474901 | 239 | setTimeout(fitscreen, 2000); // hack to allow DOM to be redrawn with new css |
72b294bb | 240 | } |
241 | ||
242 | function fitscreen() { | |
243 | /* | |
244 | * Scale body so as to fit the screen | |
245 | */ | |
246 | var heightRatio = window.innerHeight / document.body.scrollHeight; | |
247 | var widthRatio = window.innerWidth / document.body.scrollWidth; | |
6f474901 | 248 | var scaleRatio = Math.min(heightRatio, widthRatio, 1); |
72b294bb | 249 | document.body.style.transform = 'scale(' + scaleRatio + ')'; |
250 | } | |
251 | ||
252 | function insertcss() { | |
253 | /* fix positions for browsers that don't support flex */ | |
6f474901 AIL |
254 | var cssfile = document.getElementById("style"); |
255 | if(!('align-items' in document.body.style)) { | |
72b294bb | 256 | cssfile.setAttribute("href", "noflex.css"); |
257 | } | |
72b294bb | 258 | } |