function animationInterval(ms, signal, callback) { // 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(); 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); }
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter