diff options
| author | Matias Niemelä | 2013-09-03 13:29:37 -0400 | 
|---|---|---|
| committer | Matias Niemelä | 2013-09-05 17:20:28 -0400 | 
| commit | 32ad2926116e5f52ed04d788220bd389f8d0a4ac (patch) | |
| tree | 395d7209d71c760c3cb493454a47f5770da2b153 /src/ngAnimate | |
| parent | e12e584ca8db306dce8e0f4d3a212d77fbae966c (diff) | |
| download | angular.js-32ad2926116e5f52ed04d788220bd389f8d0a4ac.tar.bz2 | |
refactor($animate): use CSS3 transition/animation events instead of $timeouts to track ongoing animations
Closes #3629
Closes #3874
Diffstat (limited to 'src/ngAnimate')
| -rw-r--r-- | src/ngAnimate/animate.js | 31 | 
1 files changed, 18 insertions, 13 deletions
diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index ca136a50..d03ff643 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -549,13 +549,16 @@ angular.module('ngAnimate', ['ng'])        //one day all browsers will have these properties        var w3cAnimationProp = 'animation';        var w3cTransitionProp = 'transition'; +      var w3cAnimationEvent = 'animationend'; +      var w3cTransitionEvent = 'transitionend';        //but some still use vendor-prefixed styles        var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';        var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition'; +      var vendorAnimationEvent = $sniffer.vendorPrefix.toLowerCase() + 'AnimationEnd'; +      var vendorTransitionEvent = $sniffer.vendorPrefix.toLowerCase() + 'TransitionEnd';        var durationKey = 'Duration', -          delayKey = 'Delay',            propertyKey = 'Property',            animationIterationCountKey = 'IterationCount',            ELEMENT_NODE = 1; @@ -584,17 +587,12 @@ angular.module('ngAnimate', ['ng'])          element.addClass(className);          //we want all the styles defined before and after -        var duration = 0; +        var transitionTime = 0, +            animationTime = 0;          forEach(element, function(element) {            if (element.nodeType == ELEMENT_NODE) {              var elementStyles = $window.getComputedStyle(element) || {}; -            var transitionDelay     = Math.max(parseMaxTime(elementStyles[w3cTransitionProp     + delayKey]), -                                               parseMaxTime(elementStyles[vendorTransitionProp  + delayKey])); - -            var animationDelay      = Math.max(parseMaxTime(elementStyles[w3cAnimationProp      + delayKey]), -                                               parseMaxTime(elementStyles[vendorAnimationProp   + delayKey])); -              var transitionDuration  = Math.max(parseMaxTime(elementStyles[w3cTransitionProp     + durationKey]),                                                 parseMaxTime(elementStyles[vendorTransitionProp  + durationKey])); @@ -607,16 +605,16 @@ angular.module('ngAnimate', ['ng'])                                             1);              } -            duration = Math.max(animationDelay  + animationDuration, -                                transitionDelay + transitionDuration, -                                duration); +            transitionTime = Math.max(transitionDuration, transitionTime); +            animationTime = Math.max(animationDuration, animationTime);            }          });          /* there is no point in performing a reflow if the animation             timeout is empty (this would cause a flicker bug normally             in the page */ -        if(duration > 0) { +        var totalTime = Math.max(transitionTime,animationTime); +        if(totalTime > 0) {            var node = element[0];            //temporarily disable the transition so that the enter styles @@ -635,12 +633,15 @@ angular.module('ngAnimate', ['ng'])            node.style[vendorTransitionProp + propertyKey] = '';            element.addClass(activeClassName); -          $timeout(done, duration * 1000, false); +          var css3AnimationEvents = [w3cAnimationEvent,  vendorAnimationEvent, +                                     w3cTransitionEvent, vendorTransitionEvent].join(' '); +          element.on(css3AnimationEvents, onAnimationProgress);            //this will automatically be called by $animate so            //there is no need to attach this internally to the            //timeout done method            return function onEnd(cancelled) { +            element.off(css3AnimationEvents, onAnimationProgress);              element.removeClass(className);              element.removeClass(activeClassName); @@ -657,6 +658,10 @@ angular.module('ngAnimate', ['ng'])            done();          } +        function onAnimationProgress(event) { +          event.originalEvent.elapsedTime >= totalTime && done(); +        } +          function parseMaxTime(str) {            var total = 0, values = angular.isString(str) ? str.split(/\s*,\s*/) : [];            forEach(values, function(value) {  | 
