// References:
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// https://gist.github.com/1579671
// http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision
// https://gist.github.com/timhall/4078614
// https://github.com/Financial-Times/polyfill-service/tree/master/polyfills/requestAnimationFrame
// Expected to be used with Browserfiy
// Browserify automatically detects the use of `global` and passes the
// correct reference of `global`, `self`, and finally `window`
const ONE_FRAME_TIME = 16;
// Date.now
if (!(Date.now && Date.prototype.getTime))
{
Date.now = function now()
{
return new Date().getTime();
};
}
// performance.now
if (!(global.performance && global.performance.now))
{
const startTime = Date.now();
if (!global.performance)
{
global.performance = {};
}
global.performance.now = () => Date.now() - startTime;
}
// requestAnimationFrame
let lastTime = Date.now();
const vendors = ['ms', 'moz', 'webkit', 'o'];
for (let x = 0; x < vendors.length && !global.requestAnimationFrame; ++x)
{
const p = vendors[x];
global.requestAnimationFrame = global[`${p}RequestAnimationFrame`];
global.cancelAnimationFrame = global[`${p}CancelAnimationFrame`] || global[`${p}CancelRequestAnimationFrame`];
}
if (!global.requestAnimationFrame)
{
global.requestAnimationFrame = (callback) =>
{
if (typeof callback !== 'function')
{
throw new TypeError(`${callback}is not a function`);
}
const currentTime = Date.now();
let delay = ONE_FRAME_TIME + lastTime - currentTime;
if (delay < 0)
{
delay = 0;
}
lastTime = currentTime;
return setTimeout(() =>
{
lastTime = Date.now();
callback(performance.now());
}, delay);
};
}
if (!global.cancelAnimationFrame)
{
global.cancelAnimationFrame = (id) => clearTimeout(id);
}