aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ngAnimate/animate.js9
-rw-r--r--test/ngAnimate/animateSpec.js57
2 files changed, 60 insertions, 6 deletions
diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js
index 0e5fda98..4b35d5fd 100644
--- a/src/ngAnimate/animate.js
+++ b/src/ngAnimate/animate.js
@@ -1252,7 +1252,14 @@ angular.module('ngAnimate', ['ng'])
if(transitionDuration > 0) {
blockTransitions(element, className, isCurrentlyAnimating);
}
- if(animationDuration > 0) {
+
+ //staggering keyframe animations work by adjusting the `animation-delay` CSS property
+ //on the given element, however, the delay value can only calculated after the reflow
+ //since by that time $animate knows how many elements are being animated. Therefore,
+ //until the reflow occurs the element needs to be blocked (where the keyframe animation
+ //is set to `none 0s`). This blocking mechanism should only be set for when a stagger
+ //animation is detected and when the element item index is greater than 0.
+ if(animationDuration > 0 && stagger.animationDelay > 0 && stagger.animationDuration === 0) {
blockKeyframeAnimations(element);
}
diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js
index 9179eb2b..eaed757e 100644
--- a/test/ngAnimate/animateSpec.js
+++ b/test/ngAnimate/animateSpec.js
@@ -841,6 +841,49 @@ describe("ngAnimate", function() {
}));
+ it("should block and unblock keyframe animations when a stagger animation kicks in while skipping the first element",
+ inject(function($animate, $rootScope, $compile, $sniffer, $timeout, $document, $rootElement) {
+
+ if(!$sniffer.animations) return;
+
+ $animate.enabled(true);
+
+ ss.addRule('.blocked-animation.ng-enter',
+ '-webkit-animation:my_animation 1s;' +
+ 'animation:my_animation 1s;');
+
+ ss.addRule('.blocked-animation.ng-enter-stagger',
+ '-webkit-animation-delay:0.2s;' +
+ 'animation-delay:0.2s;');
+
+ var container = $compile(html('<div></div>'))($rootScope);
+
+ var elements = [];
+ for(var i = 0; i < 4; i++) {
+ var newScope = $rootScope.$new();
+ var element = $compile('<div class="blocked-animation"></div>')(newScope);
+ $animate.enter(element, container);
+ elements.push(element);
+ };
+
+ $rootScope.$digest();
+
+ expect(elements[0].attr('style')).toBeUndefined();
+ expect(elements[1].attr('style')).toMatch(/animation:.*?none/);
+ expect(elements[2].attr('style')).toMatch(/animation:.*?none/);
+ expect(elements[3].attr('style')).toMatch(/animation:.*?none/);
+
+ $animate.triggerReflow();
+
+ expect(elements[0].attr('style')).toBeUndefined();
+ expect(elements[1].attr('style')).not.toMatch(/animation:.*?none/);
+ expect(elements[1].attr('style')).toMatch(/animation-delay: 0.2\d*s/);
+ expect(elements[2].attr('style')).not.toMatch(/animation:.*?none/);
+ expect(elements[2].attr('style')).toMatch(/animation-delay: 0.4\d*s/);
+ expect(elements[3].attr('style')).not.toMatch(/animation:.*?none/);
+ expect(elements[3].attr('style')).toMatch(/animation-delay: 0.6\d*s/);
+ }));
+
it("should stagger items when multiple animation durations/delays are defined",
inject(function($animate, $rootScope, $compile, $sniffer, $timeout, $document, $rootElement) {
@@ -3013,7 +3056,7 @@ describe("ngAnimate", function() {
}));
- it('should block and unblock keyframe animations around the reflow operation',
+ it('should not block keyframe animations around the reflow operation',
inject(function($rootScope, $compile, $rootElement, $document, $animate, $sniffer, $timeout) {
if (!$sniffer.animations) return;
@@ -3032,15 +3075,19 @@ describe("ngAnimate", function() {
$animate.addClass(element, 'trigger-class');
- expect(node.style[animationKey]).toContain('none');
+ expect(node.style[animationKey]).not.toContain('none');
$animate.triggerReflow();
expect(node.style[animationKey]).not.toContain('none');
+
+ browserTrigger(element, 'animationend', { timeStamp: Date.now() + 1000, elapsedTime: 1 });
+
+ expect(node.style[animationKey]).not.toContain('none');
}));
- it('should block and unblock keyframe animations before the followup JS animation occurs', function() {
+ it('should not block keyframe animations at anytime before a followup JS animation occurs', function() {
module(function($animateProvider) {
$animateProvider.register('.special', function($sniffer, $window) {
var prop = $sniffer.vendorPrefix == 'Webkit' ? 'WebkitAnimation' : 'animation';
@@ -3076,8 +3123,8 @@ describe("ngAnimate", function() {
var prop = $sniffer.vendorPrefix == 'Webkit' ? 'WebkitAnimation' : 'animation';
- expect(element[0].style[prop]).toContain('none');
- expect($window.getComputedStyle(element[0])[prop + 'Duration']).toBe('0s');
+ expect(element[0].style[prop]).not.toContain('none');
+ expect($window.getComputedStyle(element[0])[prop + 'Duration']).toBe('1s');
$animate.triggerReflow();
});