hd-utils
Version:
A handy utils for modern JS developers
40 lines (37 loc) • 1.28 kB
JavaScript
import isBrowser from '../validation/isBrowser';
/**
* @description a reliable way to call a callback after a certain ms time.
* @example // Usage
const controller = new AbortController();
// Create an animation callback every second:
animationInterval(1000, controller.signal, time => {
console.log('tick!', time);
});
// And to stop it:
controller.abort();
*/
export default function animationInterval(ms, signal, callback) {
if (!isBrowser()) {
console.error('This util is for browsers only!');
return;
}
// Prefer currentTime, as it'll better sync animtions queued in the
// same frame, but if it isn't supported, performance.now() is fine.
const start = ((document?.timeline
? document?.timeline?.currentTime
: performance.now()) || 0);
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);
}