| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * request-frame - requestAnimationFrame & cancelAnimationFrame polyfill for optimal cross-browser development.
- * @version v1.5.3
- * @license MIT
- * Copyright Julien Etienne 2015 All Rights Reserved.
- */
- /**
- * @param {String} type - request | cancel | native.
- * @return {Function} Timing function.
- */
- function requestFrame(type) {
- // The only vendor prefixes required.
- const vendors = ['moz', 'webkit'];
- // Disassembled timing function abbreviations.
- const aF = 'AnimationFrame';
- const rqAF = 'Request' + aF;
- // Checks for firefox 4 - 10 function pair mismatch.
- const mozRAF = window.mozRequestAnimationFrame;
- const mozCAF = window.mozCancelAnimationFrame;
- const hasMozMismatch = mozRAF && !mozCAF;
- // Final assigned functions.
- var assignedRequestAnimationFrame;
- var assignedCancelAnimationFrame;
- // Initial time of the timing lapse.
- var previousTime = 0;
- var requestFrameMain;
- // Date.now polyfill, mainly for legacy IE versions.
- if (!Date.now) {
- Date.now = function () {
- return new Date().getTime();
- };
- }
- /**
- * hasIOS6RequestAnimationFrameBug.
- * @See {@Link https://gist.github.com/julienetie/86ac394ec41f1271ff0a}
- * - for Commentary.
- * @Copyright 2015 - Julien Etienne.
- * @License: MIT.
- */
- function hasIOS6RequestAnimationFrameBug() {
- const webkitRAF = window.webkitRequestAnimationFrame;
- const rAF = window.requestAnimationFrame;
- // CSS/ Device with max for iOS6 Devices.
- const hasMobileDeviceWidth = screen.width <= 768 ? true : false;
- // Only supports webkit prefixed requestAnimtionFrane.
- const requiresWebkitprefix = !(webkitRAF && rAF);
- // iOS6 webkit browsers don't support performance now.
- const hasNoNavigationTiming = window.performance ? false : true;
- const iOS6Notice = `setTimeout is being used as a substitiue for
- requestAnimationFrame due to a bug within iOS 6 builds`;
- const hasIOS6Bug = requiresWebkitprefix && hasMobileDeviceWidth && hasNoNavigationTiming;
- const bugCheckresults = (timingFnA, timingFnB, notice) => {
- if (timingFnA || timingFnB) {
- console.warn(notice);
- return true;
- } else {
- return false;
- }
- };
- const displayResults = (hasBug, hasBugNotice, webkitFn, nativeFn) => {
- if (hasBug) {
- return bugCheckresults(webkitFn, nativeFn, hasBugNotice);
- } else {
- return false;
- }
- };
- return displayResults(hasIOS6Bug, iOS6Notice, webkitRAF, rAF);
- }
- /**
- * Native clearTimeout function.
- * @return {Function}
- */
- function clearTimeoutWithId(id) {
- clearTimeout(id);
- }
- /**
- * Based on a polyfill by Erik, introduced by Paul Irish &
- * further improved by Darius Bacon.
- * @see {@link http://www.paulirish.com/2011/
- * requestanimationframe-for-smart-animating}
- * @see {@link https://github.com/darius/requestAnimationFrame/blob/
- * master/requestAnimationFrame.js}
- * @callback {Number} Timestamp.
- * @return {Function} setTimeout Function.
- */
- function setTimeoutWithTimestamp(callback) {
- let immediateTime = Date.now();
- let lapsedTime = Math.max(previousTime + 16, immediateTime);
- return setTimeout(function () {
- callback(previousTime = lapsedTime);
- }, lapsedTime - immediateTime);
- }
- /**
- * Queries the native function, prefixed function
- * or use the setTimeoutWithTimestamp function.
- * @return {Function}
- */
- function queryRequestAnimationFrame() {
- if (Array.prototype.filter) {
- assignedRequestAnimationFrame = window['request' + aF] || window[vendors.filter(function (vendor) {
- if (window[vendor + rqAF] !== undefined) return vendor;
- }) + rqAF] || setTimeoutWithTimestamp;
- } else {
- return setTimeoutWithTimestamp;
- }
- if (!hasIOS6RequestAnimationFrameBug()) {
- return assignedRequestAnimationFrame;
- } else {
- return setTimeoutWithTimestamp;
- }
- }
- /**
- * Queries the native function, prefixed function
- * or use the clearTimeoutWithId function.
- * @return {Function}
- */
- function queryCancelAnimationFrame() {
- let cancellationNames = [];
- if (Array.prototype.map) {
- vendors.map(function (vendor) {
- return ['Cancel', 'CancelRequest'].map(function (cancellationNamePrefix) {
- cancellationNames.push(vendor + cancellationNamePrefix + aF);
- });
- });
- } else {
- return clearTimeoutWithId;
- }
- /**
- * Checks for the prefixed cancelAnimationFrame implementation.
- * @param {Array} prefixedNames - An array of the prefixed names.
- * @param {Number} i - Iteration start point.
- * @return {Function} prefixed cancelAnimationFrame function.
- */
- function prefixedCancelAnimationFrame(prefixedNames, i) {
- let cancellationFunction;
- for (; i < prefixedNames.length; i++) {
- if (window[prefixedNames[i]]) {
- cancellationFunction = window[prefixedNames[i]];
- break;
- }
- }
- return cancellationFunction;
- }
- // Use truthly function
- assignedCancelAnimationFrame = window['cancel' + aF] || prefixedCancelAnimationFrame(cancellationNames, 0) || clearTimeoutWithId;
- // Check for iOS 6 bug
- if (!hasIOS6RequestAnimationFrameBug()) {
- return assignedCancelAnimationFrame;
- } else {
- return clearTimeoutWithId;
- }
- }
- function getRequestFn() {
- if (hasMozMismatch) {
- return setTimeoutWithTimestamp;
- } else {
- return queryRequestAnimationFrame();
- }
- }
- function getCancelFn() {
- return queryCancelAnimationFrame();
- }
- function setNativeFn() {
- if (hasMozMismatch) {
- window.requestAnimationFrame = setTimeoutWithTimestamp;
- window.cancelAnimationFrame = clearTimeoutWithId;
- } else {
- window.requestAnimationFrame = queryRequestAnimationFrame();
- window.cancelAnimationFrame = queryCancelAnimationFrame();
- }
- }
- /**
- * The type value "request" singles out firefox 4 - 10 and
- * assigns the setTimeout function if plausible.
- */
- switch (type) {
- case 'request':
- case '':
- requestFrameMain = getRequestFn();
- break;
- case 'cancel':
- requestFrameMain = getCancelFn();
- break;
- case 'native':
- setNativeFn();
- break;
- default:
- throw new Error('RequestFrame parameter is not a type.');
- }
- return requestFrameMain;
- }
- export default requestFrame;
|