4 var precision
= 100; // milliseconds
5 var defaultTime
= (15 * 60 + 0) * 1000; // milliseconds
6 var time
= defaultTime
;
8 this.isTicking
= false;
9 var outputTime
= function() {
10 document
.getElementById(id
).innerHTML
= timeToTimeStr(time
);
11 var flagid
= "flag-" + id
.split('-')[1];
12 var flagelem
= document
.getElementById(flagid
);
13 flagelem
.style
.visibility
= time
<= 0 ? "visible" : "hidden";
15 var thisTimer
= this; // workaround to use this in setInterval
16 this.tick
= function() {
17 time
-= (precision
<= time
? precision
: time
);
20 clearInterval(intervalID
);
21 thisTimer
.isTicking
= false;
25 this.start
= function() {
26 intervalID
= setInterval(this.tick
, precision
);
27 this.isTicking
= true;
29 this.stop
= function() {
30 clearInterval(intervalID
);
31 this.isTicking
= false;
33 this.setTime
= function(t
) {
38 this.getTime
= function() {
41 this.reset
= function() {
45 this.setTime(defaultTime
);
47 this.getDefaultTime
= function() {
52 var currentTimers
= new (function() {
53 this.leftTimer
= new Timer("timer-left");
54 this.rightTimer
= new Timer("timer-right");
55 this.active
= this.leftTimer
;
56 this.passive
= this.rightTimer
;
58 this.swap
= function() {
59 var tmp
= this.passive
;
60 this.passive
= this.active
;
62 var icon
= document
.getElementById("play");
63 icon
.innerHTML
= (icon
.innerHTML
== "◀" ? "▶" : "◀");
65 this.pause
= function() {
68 document
.getElementById("pause").style
.visibility
= "visible";
70 this.resume
= function() {
72 this.isPaused
= false;
73 document
.getElementById("pause").style
.visibility
= "hidden";
77 function timeStrToTime(timeStr
) {
78 var minute
= parseInt(timeStr
.substr(0, 2));
79 var second
= parseInt(timeStr
.substr(3, 2));
80 return (minute
* 60 + second
) * 1000;
83 function timeToTimeStr(time
) {
84 var minute
= Math
.floor(time
/ 1000 / 60);
85 var second
= Math
.floor(time
/ 1000) % 60;
87 minute
= '0' + minute
.toString();
90 second
= '0' + second
.toString();
92 return minute
+ ':' + second
;
95 document
.onkeydown
= function(e
) {
98 case ' ': return toggle();
100 case 's': return setTime();
102 case 'r': return reset();
104 case 'P': return pauseResume();
107 } else if(e
.keyCode
) {
109 case 32: return toggle(); // space
110 case 83: return setTime(); // S
111 case 82: return reset(); // R
112 case 80: return pauseResume(); // P
116 alert("Browser not supported");
121 if(!currentTimers
.isPaused
) {
122 currentTimers
.active
.stop();
123 currentTimers
.passive
.start();
125 currentTimers
.swap();
126 var lbt
= document
.getElementById('left-button-top');
127 var leftIsLong
= lbt
.getAttribute('class') == 'button-long';
128 var lbt_d
= lbt
.getAttribute('d').split(' ');
129 var lbb
= document
.getElementById('left-button-body');
130 var rbt
= document
.getElementById('right-button-top');
131 var rbt_d
= rbt
.getAttribute('d').split(' ');
132 var rbb
= document
.getElementById('right-button-body');
134 var y_diff
= 50 * (leftIsLong
? 1 : -1);
135 var classes
= ['button-short', 'button-long'];
137 lbt_d
[2] = (parseInt(lbt_d
[2]) + y_diff
).toString();
138 lbt_d
[10] = (parseInt(lbt_d
[10]) + y_diff
).toString();
139 lbb
.setAttribute('height',
140 (parseInt(lbb
.getAttribute('height')) - y_diff
).toString());
141 lbb
.setAttribute('y', (parseInt(lbb
.getAttribute('y')) + y_diff
).toString());
142 rbt_d
[2] = (parseInt(rbt_d
[2]) - y_diff
).toString();
143 rbt_d
[10] = (parseInt(rbt_d
[10]) - y_diff
).toString();
144 rbb
.setAttribute('height',
145 (parseInt(rbb
.getAttribute('height')) + y_diff
).toString());
146 rbb
.setAttribute('y', (parseInt(rbb
.getAttribute('y')) - y_diff
).toString());
147 lbt
.setAttribute('class', classes
[(leftIsLong
+ 1) % 2]);
148 lbb
.setAttribute('class', classes
[(leftIsLong
+ 1) % 2]);
149 rbt
.setAttribute('class', classes
[(leftIsLong
+ 1) % 2]);
150 rbb
.setAttribute('class', classes
[(leftIsLong
+ 1) % 2]);
151 lbt
.setAttribute('d', lbt_d
.join(' '));
152 rbt
.setAttribute('d', rbt_d
.join(' '));
154 lbt
.setAttribute('onclick', leftIsLong
? '' : 'toggle()');
155 lbb
.setAttribute('onclick', leftIsLong
? '' : 'toggle()');
156 lbt
.setAttribute('cursor', leftIsLong
? 'default' : 'pointer');
157 lbb
.setAttribute('cursor', leftIsLong
? 'default' : 'pointer');
158 rbt
.setAttribute('onclick', leftIsLong
? 'toggle()' : '');
159 rbb
.setAttribute('onclick', leftIsLong
? 'toggle()' : '');
160 rbt
.setAttribute('cursor', leftIsLong
? 'pointer' : 'default');
161 rbb
.setAttribute('cursor', leftIsLong
? 'pointer' : 'default');
164 function pauseResume() {
165 if(currentTimers
.isPaused
) {
166 currentTimers
.resume();
168 currentTimers
.pause();
173 var leftstart
, rightstart
;
174 var def
= timeToTimeStr(currentTimers
.leftTimer
.getDefaultTime());
175 var regex
= /[0-9][0-9]:[0-5][0-9]/;
177 leftstart
= prompt("Time for LEFT player in MM:SS", def
);
178 if(leftstart
=== null) return; // Cancel
179 while(!leftstart
.match(regex
)) {
180 leftstart
= prompt("Invalid value\nTime for LEFT player in MM:SS", def
);
181 if(leftstart
=== null) return; // Cancel
184 rightstart
= prompt("Time for RIGHT player in MM:SS", def
);
185 if(rightstart
=== null) return; // Cancel
186 while(!rightstart
.match(regex
)) {
187 rightstart
= prompt("Invalid value\nTime for RIGHT player in MM:SS", def
);
188 if(rightstart
=== null) return; // Cancel
190 currentTimers
.leftTimer
.setTime(timeStrToTime(leftstart
));
191 currentTimers
.rightTimer
.setTime(timeStrToTime(rightstart
));
195 currentTimers
.pause();
196 currentTimers
.active
.reset();
197 currentTimers
.passive
.reset();
202 setTimeout(fitscreen
, 5); // hack to allow DOM to be redrawn with new css
205 function fitscreen() {
207 * Scale body so as to fit the screen
209 var heightRatio
= window
.innerHeight
/ document
.body
.scrollHeight
;
210 var widthRatio
= window
.innerWidth
/ document
.body
.scrollWidth
;
211 var scaleRatio
= Math
.min(heightRatio
, widthRatio
);
212 document
.body
.style
.transform
= 'scale(' + scaleRatio
+ ')';
215 function insertcss() {
216 /* fix positions for browsers that don't support flex */
217 var cssfile
= document
.createElement("link");
218 cssfile
.setAttribute("rel", "stylesheet");
219 cssfile
.setAttribute("type", "text/css");
220 if('align-items' in document
.body
.style
) {
221 cssfile
.setAttribute("href", "style.css");
223 cssfile
.setAttribute("href", "noflex.css");
225 document
.head
.appendChild(cssfile
);