forked from Reimar/popup-timer
fix progress bar
This commit is contained in:
parent
382992661e
commit
60e34a4d67
112
popup/script.js
112
popup/script.js
@ -1,7 +1,9 @@
|
|||||||
var params = parseQueryParams();
|
var params = parseQueryParams();
|
||||||
|
|
||||||
// Set window title
|
// Set window title
|
||||||
if (params.name) document.title = decodeURIComponent(params.name) + " - Popup Timer";
|
if (params.name) {
|
||||||
|
document.title = decodeURIComponent(params.name) + " - Popup Timer";
|
||||||
|
}
|
||||||
|
|
||||||
var hours, minutes, seconds;
|
var hours, minutes, seconds;
|
||||||
var secondsElem = document.getElementById("seconds");
|
var secondsElem = document.getElementById("seconds");
|
||||||
@ -12,18 +14,20 @@ var progressBar = document.getElementById("progress-fg");
|
|||||||
var timeout;
|
var timeout;
|
||||||
var timesUpStr = "[ TIME'S UP! ] ";
|
var timesUpStr = "[ TIME'S UP! ] ";
|
||||||
var lastPaused = -1;
|
var lastPaused = -1;
|
||||||
|
var requiredProgress = -1;
|
||||||
|
var latestUpdate = Date.now();
|
||||||
|
var currentAnimationId = 0;
|
||||||
|
|
||||||
// Init audio
|
// Init audio
|
||||||
var oscillator, audioContext;
|
var oscillator, audioContext;
|
||||||
if (params.beep === "true") {
|
if (params.beep === "true") {
|
||||||
try {
|
try {
|
||||||
audioContext = new (window.AudioContext || window.webkitAudioContext);
|
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize clock and start
|
// Initialize clock and start
|
||||||
switch (params.type) {
|
switch (params.type) {
|
||||||
|
|
||||||
case "timer":
|
case "timer":
|
||||||
initTimer();
|
initTimer();
|
||||||
if (params.autostart === "true") startTimer(1000);
|
if (params.autostart === "true") startTimer(1000);
|
||||||
@ -40,14 +44,12 @@ switch (params.type) {
|
|||||||
|
|
||||||
// Reset timer/stopwatch
|
// Reset timer/stopwatch
|
||||||
document.getElementById("restart").onclick = function () {
|
document.getElementById("restart").onclick = function () {
|
||||||
|
|
||||||
if (timeout) clearTimeout(timeout);
|
if (timeout) clearTimeout(timeout);
|
||||||
|
|
||||||
var paused = playBtn.classList.contains("fa-play");
|
var paused = playBtn.classList.contains("fa-play");
|
||||||
|
|
||||||
switch (params.type) {
|
switch (params.type) {
|
||||||
case "timer":
|
case "timer":
|
||||||
|
|
||||||
// Reset progress bar
|
// Reset progress bar
|
||||||
progressBar.style.animationName = "none";
|
progressBar.style.animationName = "none";
|
||||||
progressBar.offsetHeight; // Trigger reflow
|
progressBar.offsetHeight; // Trigger reflow
|
||||||
@ -58,7 +60,6 @@ document.getElementById("restart").onclick = function() {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case "stopwatch":
|
case "stopwatch":
|
||||||
|
|
||||||
// Reset displayed time
|
// Reset displayed time
|
||||||
secondsElem.innerText = "00s";
|
secondsElem.innerText = "00s";
|
||||||
secondsElem.classList.remove("highlighted");
|
secondsElem.classList.remove("highlighted");
|
||||||
@ -72,16 +73,16 @@ document.getElementById("restart").onclick = function() {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Pause / Resume
|
// Pause / Resume
|
||||||
playBtn.onclick = function () {
|
playBtn.onclick = function () {
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
if (playBtn.classList.contains("fa-pause")) {
|
if (playBtn.classList.contains("fa-pause")) {
|
||||||
|
|
||||||
lastPaused = Date.now();
|
lastPaused = Date.now();
|
||||||
if (params.type === "timer") progressBar.style.animationPlayState = "paused";
|
if (params.type === "timer") {
|
||||||
|
progressBar.style.animationPlayState = "paused";
|
||||||
|
}
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
|
|
||||||
// Change icon
|
// Change icon
|
||||||
@ -90,7 +91,6 @@ playBtn.onclick = function() {
|
|||||||
|
|
||||||
// Resume
|
// Resume
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
var startOffset = lastPaused % 1000;
|
var startOffset = lastPaused % 1000;
|
||||||
|
|
||||||
switch (params.type) {
|
switch (params.type) {
|
||||||
@ -107,12 +107,11 @@ playBtn.onclick = function() {
|
|||||||
// Change icon
|
// Change icon
|
||||||
playBtn.classList.remove("fa-play");
|
playBtn.classList.remove("fa-play");
|
||||||
playBtn.classList.add("fa-pause");
|
playBtn.classList.add("fa-pause");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function initTimer() {
|
function initTimer() {
|
||||||
|
document.getElementById("progress-bg").style.width = "100%";
|
||||||
|
|
||||||
hours = parseInt(params.h);
|
hours = parseInt(params.h);
|
||||||
minutes = parseInt(params.m);
|
minutes = parseInt(params.m);
|
||||||
@ -138,35 +137,51 @@ function initTimer() {
|
|||||||
secondsElem.innerText = pad(seconds) + "s";
|
secondsElem.innerText = pad(seconds) + "s";
|
||||||
|
|
||||||
// Animate progress bar
|
// Animate progress bar
|
||||||
var totalSeconds = (hours * 60 * 60) + (minutes * 60) + seconds;
|
requiredProgress = (hours * 60 * 60) + (minutes * 60) + seconds;
|
||||||
progressBar.style.animationDuration = totalSeconds + "s";
|
++currentAnimationId;
|
||||||
progressBar.style.animationName = "progress";
|
var runId = currentAnimationId;
|
||||||
|
var animate;
|
||||||
|
animate = function () {
|
||||||
|
var paused = playBtn.classList.contains("fa-play");
|
||||||
|
if (currentAnimationId !== runId || paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var milliProgress = (Date.now() - latestUpdate) / 1000;
|
||||||
|
var progress = (hours * 60 * 60) + (minutes * 60) + seconds -
|
||||||
|
milliProgress;
|
||||||
|
var percentage = 1 - (progress /
|
||||||
|
requiredProgress);
|
||||||
|
document.getElementById("progress-fg").style.transform =
|
||||||
|
`scaleX(${percentage})`;
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
};
|
||||||
|
requestAnimationFrame(animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startTimer(startOffset) {
|
function startTimer(startOffset) {
|
||||||
|
|
||||||
if (hours === 0 && minutes == 0 && seconds === 0) return;
|
if (hours === 0 && minutes == 0 && seconds === 0) return;
|
||||||
|
|
||||||
|
latestUpdate = Date.now();
|
||||||
|
|
||||||
playBtn.classList.remove("fa-play");
|
playBtn.classList.remove("fa-play");
|
||||||
playBtn.classList.add("fa-pause");
|
playBtn.classList.add("fa-pause");
|
||||||
|
|
||||||
// Wait the starting offset
|
// Wait the starting offset
|
||||||
timeout = setTimeout(updateTimer, startOffset);
|
timeout = setTimeout(updateTimer, startOffset);
|
||||||
|
|
||||||
document.getElementById("progress-fg").style.animationPlayState = "running";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimer() {
|
function updateTimer() {
|
||||||
|
|
||||||
seconds--;
|
seconds--;
|
||||||
if (seconds === 0 && minutes === 0 && hours === 0) secondsElem.classList.remove("highlighted");
|
if (seconds === 0 && minutes === 0 && hours === 0) {
|
||||||
|
secondsElem.classList.remove("highlighted");
|
||||||
|
}
|
||||||
if (seconds <= -1) {
|
if (seconds <= -1) {
|
||||||
seconds = 59;
|
seconds = 59;
|
||||||
|
|
||||||
minutes--;
|
minutes--;
|
||||||
if (minutes === 0 && hours === 0) minutesElem.classList.remove("highlighted");
|
if (minutes === 0 && hours === 0) {
|
||||||
|
minutesElem.classList.remove("highlighted");
|
||||||
|
}
|
||||||
if (minutes <= -1) {
|
if (minutes <= -1) {
|
||||||
minutes = 59;
|
minutes = 59;
|
||||||
|
|
||||||
@ -179,24 +194,26 @@ function updateTimer() {
|
|||||||
}
|
}
|
||||||
secondsElem.innerText = pad(seconds) + "s";
|
secondsElem.innerText = pad(seconds) + "s";
|
||||||
|
|
||||||
|
latestUpdate = Date.now();
|
||||||
|
|
||||||
if (hours === 0 && minutes === 0 && seconds == 0) timeUp();
|
if (hours === 0 && minutes === 0 && seconds == 0) timeUp();
|
||||||
else timeout = setTimeout(updateTimer, 1000);
|
else timeout = setTimeout(updateTimer, 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makes the numbers blink red etc.
|
// Makes the numbers blink red etc.
|
||||||
function timeUp() {
|
function timeUp() {
|
||||||
|
|
||||||
var timeUpInterval = setInterval(function () {
|
var timeUpInterval = setInterval(function () {
|
||||||
|
|
||||||
// Blink red
|
// Blink red
|
||||||
[].slice.call(document.querySelectorAll("main > span")).forEach(function(elem) {
|
[].slice.call(document.querySelectorAll("main > span")).forEach(
|
||||||
|
function (elem) {
|
||||||
elem.classList.toggle("red");
|
elem.classList.toggle("red");
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Blink title
|
// Blink title
|
||||||
if (document.title.indexOf(timesUpStr) === -1) document.title = timesUpStr + document.title;
|
if (document.title.indexOf(timesUpStr) === -1) {
|
||||||
else document.title = document.title.substr(timesUpStr.length);
|
document.title = timesUpStr + document.title;
|
||||||
|
} else document.title = document.title.substr(timesUpStr.length);
|
||||||
|
|
||||||
// Play beep
|
// Play beep
|
||||||
if (params.beep === "true" && audioContext) {
|
if (params.beep === "true" && audioContext) {
|
||||||
@ -209,28 +226,28 @@ function timeUp() {
|
|||||||
oscillator.stop(audioContext.currentTime + 0.25);
|
oscillator.stop(audioContext.currentTime + 0.25);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// Stop when user clicks
|
// Stop when user clicks
|
||||||
document.onclick = function () {
|
document.onclick = function () {
|
||||||
|
|
||||||
if (oscillator) oscillator.stop();
|
if (oscillator) oscillator.stop();
|
||||||
|
|
||||||
// Reset color
|
// Reset color
|
||||||
[].slice.call(document.querySelectorAll("main > span")).forEach(function(elem) {
|
[].slice.call(document.querySelectorAll("main > span")).forEach(
|
||||||
|
function (elem) {
|
||||||
elem.classList.remove("red");
|
elem.classList.remove("red");
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Remove "TIME UP" from title
|
// Remove "TIME UP" from title
|
||||||
if (document.title.indexOf(timesUpStr) !== -1) document.title = document.title.substr(timesUpStr.length);
|
if (document.title.indexOf(timesUpStr) !== -1) {
|
||||||
|
document.title = document.title.substr(timesUpStr.length);
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
clearInterval(timeUpInterval);
|
clearInterval(timeUpInterval);
|
||||||
document.onclick = null;
|
document.onclick = null;
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStopwatch() {
|
function initStopwatch() {
|
||||||
@ -240,25 +257,26 @@ function initStopwatch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startStopwatch(startOffset) {
|
function startStopwatch(startOffset) {
|
||||||
|
|
||||||
playBtn.classList.remove("fa-play");
|
playBtn.classList.remove("fa-play");
|
||||||
playBtn.classList.add("fa-pause");
|
playBtn.classList.add("fa-pause");
|
||||||
|
|
||||||
timeout = setTimeout(updateStopwatch, startOffset);
|
timeout = setTimeout(updateStopwatch, startOffset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStopwatch() {
|
function updateStopwatch() {
|
||||||
|
|
||||||
// Update seconds
|
// Update seconds
|
||||||
seconds++;
|
seconds++;
|
||||||
if (hours === 0 && minutes === 0 && seconds === 1) secondsElem.classList.add("highlighted");
|
if (hours === 0 && minutes === 0 && seconds === 1) {
|
||||||
|
secondsElem.classList.add("highlighted");
|
||||||
|
}
|
||||||
if (seconds >= 60) {
|
if (seconds >= 60) {
|
||||||
seconds = 0;
|
seconds = 0;
|
||||||
|
|
||||||
// Update minutes
|
// Update minutes
|
||||||
minutes++;
|
minutes++;
|
||||||
if (hours === 0 && minutes === 1) minutesElem.classList.add("highlighted");
|
if (hours === 0 && minutes === 1) {
|
||||||
|
minutesElem.classList.add("highlighted");
|
||||||
|
}
|
||||||
if (minutes >= 60) {
|
if (minutes >= 60) {
|
||||||
minutes = 0;
|
minutes = 0;
|
||||||
|
|
||||||
@ -266,17 +284,14 @@ function updateStopwatch() {
|
|||||||
hours++;
|
hours++;
|
||||||
if (hours === 1) hoursElem.classList.add("highlighted");
|
if (hours === 1) hoursElem.classList.add("highlighted");
|
||||||
hoursElem.innerText = pad(hours) + "h";
|
hoursElem.innerText = pad(hours) + "h";
|
||||||
|
|
||||||
}
|
}
|
||||||
// Minutes
|
// Minutes
|
||||||
minutesElem.innerText = pad(minutes) + "m";
|
minutesElem.innerText = pad(minutes) + "m";
|
||||||
|
|
||||||
}
|
}
|
||||||
// Seconds
|
// Seconds
|
||||||
secondsElem.innerText = pad(seconds) + "s";
|
secondsElem.innerText = pad(seconds) + "s";
|
||||||
|
|
||||||
timeout = setTimeout(updateStopwatch, 1000);
|
timeout = setTimeout(updateStopwatch, 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseQueryParams() {
|
function parseQueryParams() {
|
||||||
@ -296,4 +311,3 @@ function parseQueryParams() {
|
|||||||
function pad(num) {
|
function pad(num) {
|
||||||
return ("00" + num).substr(-2);
|
return ("00" + num).substr(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Jetbrains Mono";
|
font-family: "Jetbrains Mono";
|
||||||
src: url("/assets/JetBrainsMono-Regular.woff2") format("woff2"),
|
src:
|
||||||
|
url("/assets/JetBrainsMono-Regular.woff2") format("woff2"),
|
||||||
url("/assets/JetBrainsMono-Regular.ttf") format("truetype");
|
url("/assets/JetBrainsMono-Regular.ttf") format("truetype");
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #FAFAFA;
|
background-color: #fafafa;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
font-family: "Jetbrains Mono", helvetica, arial, sans-serif;
|
font-family: "Jetbrains Mono", helvetica, arial, sans-serif;
|
||||||
}
|
}
|
||||||
@ -21,13 +22,13 @@ main {
|
|||||||
main > span {
|
main > span {
|
||||||
font-size: 15vw; /* Browsers that don't support min() */
|
font-size: 15vw; /* Browsers that don't support min() */
|
||||||
font-size: min(15vw, 50vh);
|
font-size: min(15vw, 50vh);
|
||||||
color: #9E9E9E;
|
color: #9e9e9e;
|
||||||
}
|
}
|
||||||
main > span.highlighted {
|
main > span.highlighted {
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
main > span.red {
|
main > span.red {
|
||||||
color: #F4511E;
|
color: #f4511e;
|
||||||
}
|
}
|
||||||
.progress {
|
.progress {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -37,28 +38,20 @@ main > span.red {
|
|||||||
width: 0;
|
width: 0;
|
||||||
}
|
}
|
||||||
#progress-bg {
|
#progress-bg {
|
||||||
background-color: #9E9E9E;
|
background-color: #9e9e9e;
|
||||||
}
|
}
|
||||||
#progress-fg {
|
#progress-fg {
|
||||||
background-color: #43A047;
|
background-color: #43a047;
|
||||||
animation-timing-function: linear;
|
width: 100%;
|
||||||
animation-fill-mode: forwards;
|
transform: scaleX(0);
|
||||||
}
|
transform-origin: center left;
|
||||||
@keyframes progress {
|
|
||||||
from {
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* FontAwesome */
|
/* FontAwesome */
|
||||||
i {
|
i {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #9E9E9E;
|
color: #9e9e9e;
|
||||||
}
|
}
|
||||||
i:hover {
|
i:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user