avocado-old/packages/timing/animation-frame.js
2019-04-19 23:12:22 -05:00

73 lines
1.7 KiB
JavaScript

// 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];
}