mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix($animate): ensure keyframe animations are blocked around the reflow
Keyframe animations trigger on the first CSS class and not the second. This may cause a slight flicker during a stagger animation since the animation has already started before the stagger delay is considered. This fix ensures that the animation is blocked until the active animation starts which allows for staggering animations to take over properly. Closes #5018
This commit is contained in:
parent
062fbed8fc
commit
6760d7a315
2 changed files with 37 additions and 0 deletions
|
|
@ -1002,6 +1002,8 @@ angular.module('ngAnimate', ['ng'])
|
|||
element.addClass(NG_ANIMATE_FALLBACK_CLASS_NAME);
|
||||
activeClassName += NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME + ' ';
|
||||
blockTransitions(element);
|
||||
} else {
|
||||
blockKeyframeAnimations(element);
|
||||
}
|
||||
|
||||
forEach(className.split(' '), function(klass, i) {
|
||||
|
|
@ -1025,6 +1027,10 @@ angular.module('ngAnimate', ['ng'])
|
|||
element[0].style[TRANSITION_PROP + PROPERTY_KEY] = 'none';
|
||||
}
|
||||
|
||||
function blockKeyframeAnimations(element) {
|
||||
element[0].style[ANIMATION_PROP] = 'none 0s';
|
||||
}
|
||||
|
||||
function unblockTransitions(element) {
|
||||
var node = element[0], prop = TRANSITION_PROP + PROPERTY_KEY;
|
||||
if(node.style[prop] && node.style[prop].length > 0) {
|
||||
|
|
@ -1032,6 +1038,10 @@ angular.module('ngAnimate', ['ng'])
|
|||
}
|
||||
}
|
||||
|
||||
function unblockKeyframeAnimations(element) {
|
||||
element[0].style[ANIMATION_PROP] = '';
|
||||
}
|
||||
|
||||
function animateRun(element, className, activeAnimationComplete) {
|
||||
var data = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
||||
if(!element.hasClass(className) || !data) {
|
||||
|
|
@ -1059,6 +1069,8 @@ angular.module('ngAnimate', ['ng'])
|
|||
style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ', ' + fallbackProperty + '; ';
|
||||
style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ', ' + timings.transitionDuration + 's; ';
|
||||
}
|
||||
} else {
|
||||
unblockKeyframeAnimations(element);
|
||||
}
|
||||
|
||||
if(ii > 0) {
|
||||
|
|
|
|||
|
|
@ -2696,4 +2696,29 @@ describe("ngAnimate", function() {
|
|||
expect(capturedProperty).not.toBe('none');
|
||||
}));
|
||||
|
||||
it('should block and unblock keyframe animations around the reflow operation',
|
||||
inject(function($rootScope, $compile, $rootElement, $document, $animate, $sniffer, $timeout) {
|
||||
|
||||
if (!$sniffer.animations) return;
|
||||
|
||||
$animate.enabled(true);
|
||||
|
||||
ss.addRule('.cross-animation', '-webkit-animation:1s my_animation;' +
|
||||
'animation:1s my_animation;');
|
||||
|
||||
var element = $compile('<div class="cross-animation"></div>')($rootScope);
|
||||
$rootElement.append(element);
|
||||
jqLite($document[0].body).append($rootElement);
|
||||
|
||||
var node = element[0];
|
||||
var animationKey = $sniffer.vendorPrefix == 'Webkit' ? 'WebkitAnimation' : 'animation';
|
||||
|
||||
$animate.addClass(element, 'trigger-class');
|
||||
|
||||
expect(node.style[animationKey]).toContain('none');
|
||||
|
||||
$timeout.flush();
|
||||
|
||||
expect(node.style[animationKey]).not.toContain('none');
|
||||
}));
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue