// Adapted from https://gist.github.com/paulirish/1579671#gistcomment-91515 let caf = undefined; let raf = undefined; // Ensure window exists. if ('undefined' !== typeof window) { raf = window.requestAnimationFrame; caf = window.cancelAnimationFrame; // Vendors? for (const vendor of ['ms', 'moz', 'webkit', 'o']) { if (raf) { break; } raf = window[`${vendor}RequestAnimationFrame`]; caf = window[`${vendor}CancelAnimationFrame`]; caf = caf || window[`${vendor}CancelRequestAnimationFrame`]; } // rAF is built in but cAF is not. if (raf && !caf) { const browserRaf = raf; const canceled = {} raf = (fn) => { const id = browserRaf((time) => { if (!(id in canceled)) { return fn(time); } delete canceled[id]; }); return id; }; caf = (id) => { canceled[id] = true; }; } } // Handle legacy browsers and node. if (!raf) { let targetTime = 0; raf = (fn) => { const currentTime = +new Date; targetTime = Math.max(targetTime + 16, currentTime); const wfn = () => { fn(+new Date); } return setTimeout(wfn, targetTime - currentTime); }; caf = (id) => { clearTimeout(id); }; } // Export what we've scrounged up. export {caf as cancelAnimationFrame}; export {raf as requestAnimationFrame}; // setInterval, but for animations. :) let said = 0 const handles = {} export function setAnimation(fn) { const id = ++said; const wfn = (time) => { if (!handles[id]) { return; } fn(time); handles[id] = raf(wfn); } handles[id] = raf(wfn); return id; } // clearInterval counterpart. export function clearAnimation (id) { caf(handles[id]); delete handles[id]; }