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