UNPKG

overscroll

Version:
108 lines (95 loc) 2.87 kB
import is from 'whatitis'; import invariant from 'invariant'; import now from 'performance-now'; var root = typeof window === 'undefined' ? global : window; var vendors = ['moz', 'webkit']; var suffix = 'AnimationFrame'; var raf = root['request' + suffix]; var caf = root['cancel' + suffix] || root['cancelRequest' + suffix]; for (var i = 0; !raf && i < vendors.length; i++) { var prefix = vendors[i]; raf = root[prefix + 'Request' + suffix]; caf = root[prefix + 'Cancel' + suffix] || root[prefix + 'CancelRequest' + suffix]; } // Some versions of FF have rAF but not cAF if (!raf || !caf) { var chain = void 0; var id = 0; var lastTime = 0; var handles = {}; var frameDuration = 1000 / 60; var throwError = function throwError(err) { return function () { throw err; }; }; var compose = function compose(callback1, callback2) { return function (lastTime) { return callback1(callback2(lastTime)); }; }; var handler = function handler(handle, next) { return function (lastTime) { if (handles[handle] !== false) { next(lastTime); } else { handles[handle] = null; } return lastTime; }; }; var next = function next(handled) { chain = chain ? compose(handled, chain) : handled; }; var toCall = function toCall() { var cp = chain; // Clear chain here to prevent // callbacks from appending listeners // to the current frame's chain chain = null; try { cp(lastTime); } catch (e) { setTimeout(throwError(e), 0); } }; raf = function raf(callback) { if (!chain) { var currTime = now(); var timeToCall = Math.max(0, frameDuration - (currTime - lastTime)); lastTime = timeToCall + currTime; root.setTimeout(toCall, Math.round(timeToCall)); } next(handler(++id, callback)); return id; }; caf = function caf(arg) { handles[arg] = false; }; } export default function polyfill() { root.requestAnimationFrame = raf; root.cancelAnimationFrame = caf; return { requestAnimationFrame: root.requestAnimationFrame, cancelAnimationFrame: root.cancelAnimationFrame }; } var _polyfill = polyfill(), requestAnimationFrame = _polyfill.requestAnimationFrame, cancelAnimationFrame = _polyfill.cancelAnimationFrame; export function requestAnimFrame(callback) { invariant(is.Function(callback), 'Expecting callback of requestAnimFrame is a function.'); var id = void 0; var getFrameHandler = function getFrameHandler() { return id; }; var cancel = function cancel() { return cancelAnimationFrame(id); }; id = requestAnimationFrame(function frameCallback(time) { callback(Math.round(time * 10) / 10, cancel); id = requestAnimationFrame(frameCallback); }); return { cancel: cancel, getFrameHandler: getFrameHandler }; }