JSFiddle - React, Tailwind, and code Playground
by nathan
HTML
<ul id="instructions" class="hideable">
<li>Press [F11] to view in fullscreen</li>
<li class="nrta countdown">Numbers at any time will reset the timer and enter a new value</li>
<li class="nrta countup">[Enter] or [Space] starts or stops the timer</li>
<li class="nrta countdown">[Enter] or [Space] starts or stops the timer, or resets it if it's at zero</li>
<li class="nrta countdown">[R] resets the timer to it's previous start value</li>
<li class="nrta countdown">[Esc] clears (zeros) the timer</li>
<li class="nrta countup">[R] or [Esc] resets the timer ([Esc] also clears the number of digits shown, but [R] doesn't)</li>
<li class="nrta countup">[Tab] shows split times</li>
<li class="nrta countdown countup">[<] and [>] ([,] and [.]) change the number of digits shown</li>
<li>[+] and [-] increase and decrease the size of the timer</li>
<li>Arrow keys move the timer around on the screen</li>
<li style="padding-top: 2em;">Press [S] to show/hide this section</li>
</ul>
<ul id="configuration" class="hideable">
<li>
<input type="radio" id="countdown-selector" name="type-selector" value="countdown" checked="checked">
<label for="countdown-selector">countdown</label>
<input type="radio" id="countup-selector" name="type-selector" value="countup">
<label for="countup-selector">stopwatch</label>
<input type="radio" id="clock-selector" name="type-selector" value="clock">
<label for="clock-selector">clock</label>
</li>
<li>
<label for="text-colour-box">Text colour</label>
<input type="text" id="text-colour-box" />
</li>
<li>
<label for="background-colour-box">Background colour</label>
<input type="text" id="background-colour-box" />
</li>
<li class="nrta countdown">
<label for="flash-colour-box">Flash colour</label>
<input type="text" id="flash-colour-box" />
</li>
</ul>
<div id="timer">
...
CSS
html {
height: 100%;
overflow: hidden;
}
body {
height: 100%;
overflow: hidden;
}
#instructions,#configuration {
width: 49%;
float: left;
margin: 0;
padding: 0;
text-indent: 0;
list-style: none;
}
#timer {
clear: both;
font-size: 10em;
}
#legal-and-ads {
position: absolute;
bottom: 0;
}
JavaScript
var Timer = function () {
var updatePeriod = 10,
proc,
systemTimeAtStart,
oldTime,
timerTimeAtStart,
resettableTime,
currentPausedTime,
countdown = true,
countup;
this.countdown = function (a) {
if (a === undefined) {
a = 0;
}
countup = false;
countdown = true;
return this.setNewTime(a);
};
this.countup = function () {
countup = true;
countdown = false;
return this.setNewTime(new Date(0));
};
this.clock = function () {
countup = false;
countdown = false;
return this.start();
};
this.start = function () {
var timerObj = this;
systemTimeAtStart = new Date();
if (timerTimeAtStart === undefined) {
timerTimeAtStart = currentPausedTime;
}
oldTime = this.getCurrentTime();
timerTimeAtStart = oldTime;
if (!countdown || this.getCurrentTime().getTime() !== 0) {
proc = window.setInterval(function () {
var current = timerObj.getCurrentTime();
if (countdown &&
current.getHours() === 23 &&
current.getMinutes() === 59 &&
current.getSeconds() === 59 &&
current.getMilliseconds() > 500) {
timerObj.update(0);
window.clearInterval(proc);
currentPausedTime = 0;
timerObj.complete();
} else {
timerObj.update(timerObj.getCurrentTime());
}
}, updatePeriod);
currentPausedTime = undefined;
}
};
this.stop = function () {
if (countdown || countup) {
currentPausedTime = this.getCurrentTime();
window.clearInterval(proc);
}
return this;
};
this.reset = function () {
currentPausedTime...