303 lines
7.2 KiB
JavaScript
303 lines
7.2 KiB
JavaScript
var params = parseQueryParams();
|
|
|
|
// Set window title
|
|
if (params.name) document.title = params.name + " - Popup Timer";
|
|
|
|
var hours, minutes, seconds;
|
|
var secondsElem = document.getElementById("seconds");
|
|
var minutesElem = document.getElementById("minutes");
|
|
var hoursElem = document.getElementById("hours");
|
|
var playBtn = document.getElementById("play");
|
|
var progressBar = document.getElementById("progress-fg");
|
|
var timeout;
|
|
var timesUpStr = "[ TIME'S UP! ] ";
|
|
var lastPaused = -1;
|
|
|
|
// Init audio
|
|
var oscillator, audioContext;
|
|
if (params.beep === "true") {
|
|
try {
|
|
audioContext = new (window.AudioContext || window.webkitAudioContext);
|
|
} catch(e) {}
|
|
}
|
|
|
|
// Autostart
|
|
if (params.autostart === "true") {
|
|
|
|
switch (params.type) {
|
|
|
|
case "timer":
|
|
initTimer();
|
|
startTimer(1000);
|
|
break;
|
|
|
|
case "stopwatch":
|
|
initStopwatch();
|
|
startStopwatch(1000);
|
|
break;
|
|
|
|
default:
|
|
location.href = "/";
|
|
}
|
|
|
|
}
|
|
|
|
// Reset timer/stopwatch
|
|
document.getElementById("restart").onclick = function() {
|
|
|
|
if (timeout) clearTimeout(timeout);
|
|
|
|
var paused = playBtn.classList.contains("fa-play");
|
|
|
|
switch (params.type) {
|
|
case "timer":
|
|
|
|
// Reset progress bar
|
|
// TODO
|
|
progressBar.animationName = "";
|
|
progressBar.animationName = "progress";
|
|
|
|
initTimer();
|
|
if (!paused) startTimer(1000);
|
|
|
|
break;
|
|
case "stopwatch":
|
|
|
|
// Reset displayed time
|
|
secondsElem.innerText = "00s";
|
|
secondsElem.classList.remove("highlighted");
|
|
minutesElem.innerText = "00m";
|
|
minutesElem.classList.remove("highlighted");
|
|
hoursElem.innerText = "00h";
|
|
hoursElem.classList.remove("highlighted");
|
|
|
|
initStopwatch();
|
|
if (!paused) startStopwatch(1000);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Pause / Resume
|
|
playBtn.onclick = function() {
|
|
|
|
if (!timeout) return;
|
|
|
|
// Pause
|
|
if (playBtn.classList.contains("fa-pause")) {
|
|
|
|
lastPaused = Date.now();
|
|
if (params.type === "timer") progressBar.style.animationPlayState = "paused";
|
|
clearTimeout(timeout);
|
|
|
|
// Change icon
|
|
playBtn.classList.remove("fa-pause");
|
|
playBtn.classList.add("fa-play");
|
|
|
|
// Resume
|
|
} else {
|
|
|
|
var startOffset = lastPaused % 1000;
|
|
|
|
switch (params.type) {
|
|
case "timer":
|
|
if (hours === 0 && minutes == 0 && seconds === 0) return;
|
|
progressBar.style.animationPlayState = "running";
|
|
startTimer(startOffset);
|
|
break;
|
|
case "stopwatch":
|
|
startStopwatch(startOffset);
|
|
break;
|
|
}
|
|
|
|
// Change icon
|
|
playBtn.classList.remove("fa-play");
|
|
playBtn.classList.add("fa-pause");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function initTimer() {
|
|
|
|
hours = parseInt(params.h);
|
|
minutes = parseInt(params.m);
|
|
seconds = parseInt(params.s);
|
|
|
|
if (hours === 0 && minutes === 0 && seconds === 0) return;
|
|
|
|
// Only highlight relevant parts
|
|
if (hours > 0) {
|
|
hoursElem.classList.add("highlighted");
|
|
minutesElem.classList.add("highlighted");
|
|
secondsElem.classList.add("highlighted");
|
|
} else if (minutes > 0) {
|
|
minutesElem.classList.add("highlighted");
|
|
secondsElem.classList.add("highlighted");
|
|
} else {
|
|
secondsElem.classList.add("highlighted");
|
|
}
|
|
|
|
// Print initial time
|
|
hoursElem.innerText = pad(hours) + "h";
|
|
minutesElem.innerText = pad(minutes) + "m";
|
|
secondsElem.innerText = pad(seconds) + "s";
|
|
|
|
// Animate progress bar
|
|
var totalSeconds = (hours * 60 * 60) + (minutes * 60) + seconds;
|
|
progressBar.style.animationDuration = totalSeconds + "s";
|
|
progressBar.style.animationName = "progress";
|
|
|
|
}
|
|
|
|
function startTimer(startOffset) {
|
|
|
|
playBtn.classList.remove("fa-play");
|
|
playBtn.classList.add("fa-pause");
|
|
|
|
// Wait the starting offset
|
|
timeout = setTimeout(updateTimer, startOffset);
|
|
|
|
document.getElementById("progress-fg").style.animationPlayState = "running";
|
|
|
|
}
|
|
|
|
function updateTimer() {
|
|
|
|
seconds--;
|
|
if (seconds === 0 && minutes === 0 && hours === 0) secondsElem.classList.remove("highlighted");
|
|
if (seconds <= -1) {
|
|
seconds = 59;
|
|
|
|
minutes--;
|
|
if (minutes === 0 && hours === 0) minutesElem.classList.remove("highlighted");
|
|
if (minutes <= -1) {
|
|
minutes = 59;
|
|
|
|
hours--;
|
|
if (hours === 0) hoursElem.classList.remove("highlighted");
|
|
|
|
hoursElem.innerText = pad(hours) + "h";
|
|
}
|
|
minutesElem.innerText = pad(minutes) + "m";
|
|
}
|
|
secondsElem.innerText = pad(seconds) + "s";
|
|
|
|
if (hours === 0 && minutes === 0 && seconds == 0) timeUp();
|
|
else timeout = setTimeout(updateTimer, 1000);
|
|
|
|
}
|
|
|
|
// Makes the numbers blink red etc.
|
|
function timeUp() {
|
|
|
|
var timeUpInterval = setInterval(function() {
|
|
|
|
// Blink red
|
|
[].slice.call(document.querySelectorAll("main > span")).forEach(function(elem) {
|
|
elem.classList.toggle("red");
|
|
});
|
|
//document.querySelector
|
|
|
|
// Blink title
|
|
if (document.title.indexOf(timesUpStr) === -1) document.title = timesUpStr + document.title;
|
|
else document.title = document.title.substr(timesUpStr.length);
|
|
|
|
// Play beep
|
|
if (params.beep === "true" && audioContext) {
|
|
try {
|
|
oscillator = audioContext.createOscillator();
|
|
oscillator.type = "sine";
|
|
oscillator.frequency.value = 1000;
|
|
oscillator.connect(audioContext.destination);
|
|
oscillator.start();
|
|
oscillator.stop(audioContext.currentTime + 0.25);
|
|
} catch(e) {}
|
|
}
|
|
|
|
}, 500);
|
|
|
|
// Stop when user clicks
|
|
document.onclick = function() {
|
|
|
|
if (oscillator) oscillator.stop();
|
|
|
|
// Reset color
|
|
[].slice.call(document.querySelectorAll("main > span")).forEach(function(elem) {
|
|
elem.classList.remove("red");
|
|
});
|
|
|
|
// Remove "TIME UP" from title
|
|
if (document.title.indexOf(timesUpStr) !== -1) document.title = document.title.substr(timesUpStr.length);
|
|
|
|
// Clean up
|
|
clearInterval(timeUpInterval);
|
|
document.onclick = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function initStopwatch() {
|
|
hours = 0;
|
|
minutes = 0;
|
|
seconds = 0;
|
|
}
|
|
|
|
function startStopwatch(startOffset) {
|
|
|
|
playBtn.classList.remove("fa-play");
|
|
playBtn.classList.add("fa-pause");
|
|
|
|
timeout = setTimeout(updateStopwatch, startOffset);
|
|
|
|
}
|
|
|
|
function updateStopwatch() {
|
|
|
|
// Update seconds
|
|
seconds++;
|
|
if (hours === 0 && minutes === 0 && seconds === 1) secondsElem.classList.add("highlighted");
|
|
if (seconds >= 60) {
|
|
seconds = 0;
|
|
|
|
// Update minutes
|
|
minutes++;
|
|
if (hours === 0 && minutes === 1) minutesElem.classList.add("highlighted");
|
|
if (minutes >= 60) {
|
|
minutes = 0;
|
|
|
|
// Update hours
|
|
hours++;
|
|
if (hours === 1) hoursElem.classList.add("highlighted");
|
|
hoursElem.innerText = pad(hours) + "h";
|
|
|
|
}
|
|
// Minutes
|
|
minutesElem.innerText = pad(minutes) + "m";
|
|
|
|
}
|
|
// Seconds
|
|
secondsElem.innerText = pad(seconds) + "s";
|
|
|
|
timeout = setTimeout(updateStopwatch, 1000);
|
|
|
|
}
|
|
|
|
function parseQueryParams() {
|
|
if (location.search === "" || location.search.indexOf("?") !== 0) return {};
|
|
var result = {};
|
|
location.search.substr(1).split("&").forEach(function(str) {
|
|
var key = str.split("=")[0];
|
|
var value;
|
|
if (str.split("=").length > 1) value = str.split("=")[1];
|
|
else value = null;
|
|
result[key] = value;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
// Adds one leading zero if necessary
|
|
function pad(num) {
|
|
return ("00" + num).substr(-2);
|
|
} |