From 72b294bb37da204ea6993cf27361cdc945315db9 Mon Sep 17 00:00:00 2001 From: adrianiainlam Date: Tue, 2 Feb 2016 01:09:34 +0000 Subject: [PATCH] Going home; wasn't welcome there --- index.html | 54 +++++++++++++++ noflex.css | 97 ++++++++++++++++++++++++++ script.js | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 85 +++++++++++++++++++++++ 4 files changed, 462 insertions(+) create mode 100644 index.html create mode 100644 noflex.css create mode 100644 script.js create mode 100644 style.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..6785a3a --- /dev/null +++ b/index.html @@ -0,0 +1,54 @@ + + + + + JSChessClock + + + + +

JSChessClock

+ +
+ + + + + + + + + + +
+
+
+
+
+
15:00
+
+
❚❚
+
◀
+
+
15:00
+
+
+
[S]et time
+
[R]eset to previous
+
[P]ause / resume
+
[space] Toggle
+
+
+ + diff --git a/noflex.css b/noflex.css new file mode 100644 index 0000000..b57e0ea --- /dev/null +++ b/noflex.css @@ -0,0 +1,97 @@ +body { + transform-origin: 0 0; + overflow: hidden; + text-align: center; +} + +.clock-container { + position: relative; + width: 650px; + margin-left: auto; + margin-right: auto; +} + +.flags > div { + display: inline-block; + visibility: hidden; + animation: blinker 1s linear infinite; + font-size: 200%; + font-family: "DejaVu Sans",FreeSerif,Code2000,"BabelStone Han","Lucida Sans"; +} + +#flag-left { + position: absolute; + top: 35%; + z-index: 9999; + left: 5%; +} +#flag-right { + position: absolute; + top: 35%; + z-index: 9999; + right: 5%; +} + +@keyframes blinker { + 50% { opacity: 0; } +} + +.timers { + clear: both; + width: 530px; /* 570, -40 for aesthetic reason */ + position: absolute; + top: 50%; + z-index: 9999; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; +} + +.timer { + font-size: 400%; + display: inline-block; +} + +#timer-left { + float: left; +} +#timer-right { + float: right; +} + +.indicators { + font-size: 167%; + display: inline-block; + position: absolute; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; +} + +h1 { + text-align: center; +} + +.commands { + clear: both; + margin: 0 auto; + width: 650px; + position: absolute; + left: 0; + right: 0; + margin-left: auto; + margin-right:auto; + bottom: 5%; + z-index: 9999; +} + +.cmd { + display: inline-block; + cursor: pointer; + background-color: #FFF; + padding: 5px; + border: 3px solid #800000; + border-radius: 5px; +} diff --git a/script.js b/script.js new file mode 100644 index 0000000..3e524f4 --- /dev/null +++ b/script.js @@ -0,0 +1,226 @@ +"use strict"; + +function Timer(id) { + var precision = 100; // milliseconds + var defaultTime = (15 * 60 + 0) * 1000; // milliseconds + var time = defaultTime; + var intervalID; + this.isTicking = false; + var outputTime = function() { + document.getElementById(id).innerHTML = timeToTimeStr(time); + var flagid = "flag-" + id.split('-')[1]; + var flagelem = document.getElementById(flagid); + flagelem.style.visibility = time <= 0 ? "visible" : "hidden"; + }; + var thisTimer = this; // workaround to use this in setInterval + this.tick = function() { + time -= (precision <= time ? precision : time); + if(time <= 0) { + // time's up + clearInterval(intervalID); + thisTimer.isTicking = false; + } + outputTime(); + }; + this.start = function() { + intervalID = setInterval(this.tick, precision); + this.isTicking = true; + }; + this.stop = function() { + clearInterval(intervalID); + this.isTicking = false; + }; + this.setTime = function(t) { + time = t; + defaultTime = t; + outputTime(); + }; + this.getTime = function() { + return time; + }; + this.reset = function() { + if(this.isTicking) { + this.stop(); + } + this.setTime(defaultTime); + }; + this.getDefaultTime = function() { + return defaultTime; + }; +} + +var currentTimers = new (function() { + this.leftTimer = new Timer("timer-left"); + this.rightTimer = new Timer("timer-right"); + this.active = this.leftTimer; + this.passive = this.rightTimer; + this.isPaused = true; + this.swap = function() { + var tmp = this.passive; + this.passive = this.active; + this.active = tmp; + var icon = document.getElementById("play"); + icon.innerHTML = (icon.innerHTML == "◀" ? "▶" : "◀"); + }; + this.pause = function() { + this.active.stop(); + this.isPaused = true; + document.getElementById("pause").style.visibility = "visible"; + }; + this.resume = function() { + this.active.start(); + this.isPaused = false; + document.getElementById("pause").style.visibility = "hidden"; + }; +})(); + +function timeStrToTime(timeStr) { + var minute = parseInt(timeStr.substr(0, 2)); + var second = parseInt(timeStr.substr(3, 2)); + return (minute * 60 + second) * 1000; +} + +function timeToTimeStr(time) { + var minute = Math.floor(time / 1000 / 60); + var second = Math.floor(time / 1000) % 60; + if(minute < 10) { + minute = '0' + minute.toString(); + } + if(second < 10) { + second = '0' + second.toString(); + } + return minute + ':' + second; +} + +document.onkeydown = function(e) { + if(e.key) { + switch(e.key) { + case ' ': return toggle(); + case 'S': + case 's': return setTime(); + case 'R': + case 'r': return reset(); + case 'p': + case 'P': return pauseResume(); + default: return; + } + } else if(e.keyCode) { + switch(e.keyCode) { + case 32: return toggle(); // space + case 83: return setTime(); // S + case 82: return reset(); // R + case 80: return pauseResume(); // P + default: return; + } + } else { + alert("Browser not supported"); + } +}; + +function toggle() { + if(!currentTimers.isPaused) { + currentTimers.active.stop(); + currentTimers.passive.start(); + } + currentTimers.swap(); + var lbt = document.getElementById('left-button-top'); + var leftIsLong = lbt.getAttribute('class') == 'button-long'; + var lbt_d = lbt.getAttribute('d').split(' '); + var lbb = document.getElementById('left-button-body'); + var rbt = document.getElementById('right-button-top'); + var rbt_d = rbt.getAttribute('d').split(' '); + var rbb = document.getElementById('right-button-body'); + + var y_diff = 50 * (leftIsLong ? 1 : -1); + var classes = ['button-short', 'button-long']; + + lbt_d[2] = (parseInt(lbt_d[2]) + y_diff).toString(); + lbt_d[10] = (parseInt(lbt_d[10]) + y_diff).toString(); + lbb.setAttribute('height', + (parseInt(lbb.getAttribute('height')) - y_diff).toString()); + lbb.setAttribute('y', (parseInt(lbb.getAttribute('y')) + y_diff).toString()); + rbt_d[2] = (parseInt(rbt_d[2]) - y_diff).toString(); + rbt_d[10] = (parseInt(rbt_d[10]) - y_diff).toString(); + rbb.setAttribute('height', + (parseInt(rbb.getAttribute('height')) + y_diff).toString()); + rbb.setAttribute('y', (parseInt(rbb.getAttribute('y')) - y_diff).toString()); + lbt.setAttribute('class', classes[(leftIsLong + 1) % 2]); + lbb.setAttribute('class', classes[(leftIsLong + 1) % 2]); + rbt.setAttribute('class', classes[(leftIsLong + 1) % 2]); + rbb.setAttribute('class', classes[(leftIsLong + 1) % 2]); + lbt.setAttribute('d', lbt_d.join(' ')); + rbt.setAttribute('d', rbt_d.join(' ')); + + lbt.setAttribute('onclick', leftIsLong ? '' : 'toggle()'); + lbb.setAttribute('onclick', leftIsLong ? '' : 'toggle()'); + lbt.setAttribute('cursor', leftIsLong ? 'default' : 'pointer'); + lbb.setAttribute('cursor', leftIsLong ? 'default' : 'pointer'); + rbt.setAttribute('onclick', leftIsLong ? 'toggle()' : ''); + rbb.setAttribute('onclick', leftIsLong ? 'toggle()' : ''); + rbt.setAttribute('cursor', leftIsLong ? 'pointer' : 'default'); + rbb.setAttribute('cursor', leftIsLong ? 'pointer' : 'default'); +} + +function pauseResume() { + if(currentTimers.isPaused) { + currentTimers.resume(); + } else { + currentTimers.pause(); + } +} + +function setTime() { + var leftstart, rightstart; + var def = timeToTimeStr(currentTimers.leftTimer.getDefaultTime()); + var regex = /[0-9][0-9]:[0-5][0-9]/; + + leftstart = prompt("Time for LEFT player in MM:SS", def); + if(leftstart === null) return; // Cancel + while(!leftstart.match(regex)) { + leftstart = prompt("Invalid value\nTime for LEFT player in MM:SS", def); + if(leftstart === null) return; // Cancel + } + def = leftstart; + rightstart = prompt("Time for RIGHT player in MM:SS", def); + if(rightstart === null) return; // Cancel + while(!rightstart.match(regex)) { + rightstart = prompt("Invalid value\nTime for RIGHT player in MM:SS", def); + if(rightstart === null) return; // Cancel + } + currentTimers.leftTimer.setTime(timeStrToTime(leftstart)); + currentTimers.rightTimer.setTime(timeStrToTime(rightstart)); +} + +function reset() { + currentTimers.pause(); + currentTimers.active.reset(); + currentTimers.passive.reset(); +} + +function init() { + insertcss(); + setTimeout(fitscreen, 5); // hack to allow DOM to be redrawn with new css +} + +function fitscreen() { + /* + * Scale body so as to fit the screen + */ + var heightRatio = window.innerHeight / document.body.scrollHeight; + var widthRatio = window.innerWidth / document.body.scrollWidth; + var scaleRatio = Math.min(heightRatio, widthRatio); + document.body.style.transform = 'scale(' + scaleRatio + ')'; +} + +function insertcss() { + /* fix positions for browsers that don't support flex */ + var cssfile = document.createElement("link"); + cssfile.setAttribute("rel", "stylesheet"); + cssfile.setAttribute("type", "text/css"); + if('align-items' in document.body.style) { + cssfile.setAttribute("href", "style.css"); + } else { + cssfile.setAttribute("href", "noflex.css"); + } + document.head.appendChild(cssfile); +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..5a8c6e6 --- /dev/null +++ b/style.css @@ -0,0 +1,85 @@ +body { + transform-origin: 0 0; + overflow: hidden; + text-align: center; +} + +.clock-container { + position: relative; +} + +.flags { + width: 570px; + display: flex; + justify-content: space-between; + position: absolute; + top: 40%; + z-index: 9999; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; +} + +.flags > div { + visibility: hidden; + animation: blinker 1s linear infinite; + font-size: 25pt; + font-family: "DejaVu Sans",FreeSerif,Code2000,"BabelStone Han","Lucida Sans"; +} + +@keyframes blinker { + 50% { opacity: 0; } +} + +.timers { + width: 650px; + display: flex; + justify-content: center; + align-items: center; + /*margin-bottom: 96pt;*/ + position: absolute; + top: 50%; + z-index: 9999; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; +} + +.timer { + margin-left: 48pt; + margin-right: 48pt; + font-size: 48pt; +} + +.indicators { + width: 20pt; + font-size: 20pt; +} + +h1 { + text-align: center; +} + +.commands { + margin: 0 auto; + width: 650px; + display: flex; + justify-content: space-around; + position: absolute; + left: 0; + right: 0; + margin-left: auto; + margin-right:auto; + bottom: 5%; + z-index: 9999; +} + +.cmd { + cursor: pointer; + background-color: #FFF; + padding: 5px; + border: 3px solid #800000; + border-radius: 5px; +} -- 2.7.4