/* rAF * ---------------------------------------------------------------------------- * cross-browser (IE 8+) animation framework with easings * * url : https://gist.github.com/imthenachoman/d19dc4cf6e53ad3664ea * author : Anchal Nigam * e-mail : imthenachoman@gmail.com * * Copyright (c) 2015 Anchal Nigam (imthenachoman@gmail.com) * Licensed under the MIT license: http://opensource.org/licenses/MIT * ---------------------------------------------------------------------------- */ var animate = (function() { // store each animation so we can cancel them later var animationCounter = 0, animationIDTracker = {}; var lastTime = 0, vendors = ['ms', 'moz', 'webkit', 'o']; // easing functions var easingFunctions = { linear: function (t) { return t }, easeInQuad: function (t) { return t*t }, easeOutQuad: function (t) { return t*(2-t) }, easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t }, easeInCubic: function (t) { return t*t*t }, easeOutCubic: function (t) { return (--t)*t*t+1 }, easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 }, easeInQuart: function (t) { return t*t*t*t }, easeOutQuart: function (t) { return 1-(--t)*t*t*t }, easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t }, easeInQuint: function (t) { return t*t*t*t*t }, easeOutQuint: function (t) { return 1+(--t)*t*t*t*t }, easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t } }; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if(!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if(!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; // to animate return { // stop an animation "stop" : function(id) { cancelAnimationFrame(animationIDTracker[id]); }, // start an animation // duration = time in milliseconds // action = function to call on each iteration; will be passed a rate paramater which equals to the percent complete (0 = starting; 1 = done) // easing is an optional easing function "start" : function(duration, action, easing) { var currentAnimationID = animationCounter++; var end = +new Date() + duration; var step = function() { var remaining = end - (+new Date()); if( remaining < 60) { action(1); delete animationIDTracker[currentAnimationID]; return; } else { action(1 - easingFunctions[easing || "linear"](remaining/duration)); } animationIDTracker[currentAnimationID] = requestAnimationFrame(step); }; step(); return currentAnimationID; } }; })(); /* * References: * - jquery style animations using requestAnimationFrame with easing * - requestAnimationFrame - https://gist.github.com/paulirish/1579671 * - animations - http://www.sitepoint.com/simple-animations-using-requestanimationframe/ * - easing functions - https://gist.github.com/gre/1650294 */