Skip to content

Instantly share code, notes, and snippets.

@mscalora
Last active March 15, 2021 13:38
Show Gist options
  • Save mscalora/072cc6ece562107907a4d151b1d70bac to your computer and use it in GitHub Desktop.
Save mscalora/072cc6ece562107907a4d151b1d70bac to your computer and use it in GitHub Desktop.
Perfect JS Counter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Counter</title>
<style>
html {
height: 100%;
margin: 0;
padding: 0;
background: black;
color: white;
}
body {
min-height: 100vh;
margin: 0;
padding: 0;
display: grid;
place-items: center;
text-align: center;
}
#container {
border: 2px solid white;
padding: 1em 2em;
}
button {
position: fixed;
bottom: 4px;
right: 4px;
}
</style>
</head>
<body>
<div>
<div id="container">0</div>
<div><a href="https://www.youtube.com/watch?v=MCi6AZMkxcU" target="_blank">video</a></div>
</div>
<button id="stop" type="button">stop</button>
<script>
function animationInterval(ms, signal, callback) {
// Prefer currentTime, as it'll better sync animations queued in the
// same frame, but if it isn't supported, performance.now() is fine.
const start = document.timeline ? document.timeline.currentTime : performance.now();
function frame(time) {
if (signal.aborted) return;
callback(time);
scheduleFrame(time);
}
function scheduleFrame(time) {
const elapsed = time - start;
const roundedElapsed = Math.round(elapsed / ms) * ms;
const targetNext = start + roundedElapsed + ms;
const delay = targetNext - performance.now();
setTimeout(() => requestAnimationFrame(frame), delay);
}
scheduleFrame(start);
}
const controller = new AbortController();
animationInterval(1000, controller.signal, time => {
let container = document.getElementById('container');
if (container) {
container.innerHTML = Math.round(time/1000).toString();
}
});
let stopper = document.getElementById('stop');
stopper.addEventListener('click', () => {controller.abort(); stopper.style.display = 'none';});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment