From 4c4537e65e6cf911c9659b562d89e3330ce3ffae Mon Sep 17 00:00:00 2001 From: Matias Niemelä Date: Mon, 24 Feb 2014 19:43:57 -0500 Subject: perf($animate): use rAF instead of timeouts to issue animation callbacks --- src/ngAnimate/animate.js | 54 ++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) (limited to 'src/ngAnimate') diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index 5c0ed917..6ccf6a5d 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -247,42 +247,24 @@ angular.module('ngAnimate', ['ng']) * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application. * */ - .factory('$$animateReflow', ['$window', '$timeout', '$document', - function($window, $timeout, $document) { + + //this private service is only used within CSS-enabled animations + //IE8 + IE9 do not support rAF natively, but that is fine since they + //also don't support transitions and keyframes which means that the code + //below will never be used by the two browsers. + .factory('$$animateReflow', ['$$rAF', '$document', function($$rAF, $document) { var bod = $document[0].body; - var requestAnimationFrame = $window.requestAnimationFrame || - $window.webkitRequestAnimationFrame || - function(fn) { - return $timeout(fn, 10, false); - }; - - var cancelAnimationFrame = $window.cancelAnimationFrame || - $window.webkitCancelAnimationFrame || - function(timer) { - return $timeout.cancel(timer); - }; return function(fn) { - var id = requestAnimationFrame(function() { + //the returned function acts as the cancellation function + return $$rAF(function() { + //the line below will force the browser to perform a repaint + //so that all the animated elements within the animation frame + //will be properly updated and drawn on screen. This is + //required to perform multi-class CSS based animations with + //Firefox. DO NOT REMOVE THIS LINE. var a = bod.offsetWidth + 1; fn(); }); - return function() { - cancelAnimationFrame(id); - }; - }; - }]) - - .factory('$$asyncQueueBuffer', ['$timeout', function($timeout) { - var timer, queue = []; - return function(fn) { - $timeout.cancel(timer); - queue.push(fn); - timer = $timeout(function() { - for(var i = 0; i < queue.length; i++) { - queue[i](); - } - queue = []; - }, 0, false); }; }]) @@ -313,8 +295,8 @@ angular.module('ngAnimate', ['ng']) return extractElementNode(elm1) == extractElementNode(elm2); } - $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$$asyncQueueBuffer', '$rootScope', '$document', - function($delegate, $injector, $sniffer, $rootElement, $$asyncQueueBuffer, $rootScope, $document) { + $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$$asyncCallback', '$rootScope', '$document', + function($delegate, $injector, $sniffer, $rootElement, $$asyncCallback, $rootScope, $document) { var globalAnimationCounter = 0; $rootElement.data(NG_ANIMATE_STATE, rootAnimateState); @@ -876,7 +858,7 @@ angular.module('ngAnimate', ['ng']) function fireDOMCallback(animationPhase) { var eventName = '$animate:' + animationPhase; if(elementEvents && elementEvents[eventName] && elementEvents[eventName].length > 0) { - $$asyncQueueBuffer(function() { + $$asyncCallback(function() { element.triggerHandler(eventName, { event : animationEvent, className : className @@ -896,7 +878,7 @@ angular.module('ngAnimate', ['ng']) function fireDoneCallbackAsync() { fireDOMCallback('close'); if(doneCallback) { - $$asyncQueueBuffer(function() { + $$asyncCallback(function() { doneCallback(); }); } @@ -923,7 +905,7 @@ angular.module('ngAnimate', ['ng']) if(isClassBased) { cleanup(element, className); } else { - $$asyncQueueBuffer(function() { + $$asyncCallback(function() { var data = element.data(NG_ANIMATE_STATE) || {}; if(localAnimationCount == data.index) { cleanup(element, className, animationEvent); -- cgit v1.2.3