mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix($animate): ensure the final closing timeout respects staggering animations
This commit is contained in:
parent
6df598d9f5
commit
ed53100a0d
2 changed files with 56 additions and 10 deletions
|
|
@ -930,8 +930,12 @@ angular.module('ngAnimate', ['ng'])
|
||||||
animationElementQueue.push(element);
|
animationElementQueue.push(element);
|
||||||
|
|
||||||
var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
|
||||||
closingAnimationTime = Math.max(closingAnimationTime,
|
|
||||||
(elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER * ONE_SECOND);
|
var stagger = elementData.stagger;
|
||||||
|
var staggerTime = elementData.itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0);
|
||||||
|
|
||||||
|
var animationTime = (elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER;
|
||||||
|
closingAnimationTime = Math.max(closingAnimationTime, (staggerTime + animationTime) * ONE_SECOND);
|
||||||
|
|
||||||
//by placing a counter we can avoid an accidental
|
//by placing a counter we can avoid an accidental
|
||||||
//race condition which may close an animation when
|
//race condition which may close an animation when
|
||||||
|
|
@ -1058,9 +1062,9 @@ angular.module('ngAnimate', ['ng'])
|
||||||
var cacheKey = getCacheKey(element);
|
var cacheKey = getCacheKey(element);
|
||||||
var eventCacheKey = cacheKey + ' ' + className;
|
var eventCacheKey = cacheKey + ' ' + className;
|
||||||
var stagger = {};
|
var stagger = {};
|
||||||
var ii = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
|
var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
|
||||||
|
|
||||||
if(ii > 0) {
|
if(itemIndex > 0) {
|
||||||
var staggerClassName = className + '-stagger';
|
var staggerClassName = className + '-stagger';
|
||||||
var staggerCacheKey = cacheKey + ' ' + staggerClassName;
|
var staggerCacheKey = cacheKey + ' ' + staggerClassName;
|
||||||
var applyClasses = !lookupCache[staggerCacheKey];
|
var applyClasses = !lookupCache[staggerCacheKey];
|
||||||
|
|
@ -1113,7 +1117,7 @@ angular.module('ngAnimate', ['ng'])
|
||||||
classes : className + ' ' + activeClassName,
|
classes : className + ' ' + activeClassName,
|
||||||
timings : timings,
|
timings : timings,
|
||||||
stagger : stagger,
|
stagger : stagger,
|
||||||
ii : ii
|
itemIndex : itemIndex
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1158,7 +1162,7 @@ angular.module('ngAnimate', ['ng'])
|
||||||
var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * ONE_SECOND;
|
var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * ONE_SECOND;
|
||||||
var startTime = Date.now();
|
var startTime = Date.now();
|
||||||
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
|
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
|
||||||
var ii = elementData.ii;
|
var itemIndex = elementData.itemIndex;
|
||||||
|
|
||||||
var style = '', appliedStyles = [];
|
var style = '', appliedStyles = [];
|
||||||
if(timings.transitionDuration > 0) {
|
if(timings.transitionDuration > 0) {
|
||||||
|
|
@ -1171,17 +1175,17 @@ angular.module('ngAnimate', ['ng'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ii > 0) {
|
if(itemIndex > 0) {
|
||||||
if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
|
if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
|
||||||
var delayStyle = timings.transitionDelayStyle;
|
var delayStyle = timings.transitionDelayStyle;
|
||||||
style += CSS_PREFIX + 'transition-delay: ' +
|
style += CSS_PREFIX + 'transition-delay: ' +
|
||||||
prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; ';
|
prepareStaggerDelay(delayStyle, stagger.transitionDelay, itemIndex) + '; ';
|
||||||
appliedStyles.push(CSS_PREFIX + 'transition-delay');
|
appliedStyles.push(CSS_PREFIX + 'transition-delay');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
|
if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
|
||||||
style += CSS_PREFIX + 'animation-delay: ' +
|
style += CSS_PREFIX + 'animation-delay: ' +
|
||||||
prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, ii) + '; ';
|
prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, itemIndex) + '; ';
|
||||||
appliedStyles.push(CSS_PREFIX + 'animation-delay');
|
appliedStyles.push(CSS_PREFIX + 'animation-delay');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1155,7 +1155,7 @@ describe("ngAnimate", function() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
it("apply a closing timeout to close all pending transitions",
|
it("should apply a closing timeout to close all pending transitions",
|
||||||
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
|
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
|
||||||
|
|
||||||
if (!$sniffer.transitions) return;
|
if (!$sniffer.transitions) return;
|
||||||
|
|
@ -1174,6 +1174,48 @@ describe("ngAnimate", function() {
|
||||||
expect(element.hasClass('some-class-add-active')).toBe(false);
|
expect(element.hasClass('some-class-add-active')).toBe(false);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it("apply a closing timeout with respect to a staggering animation",
|
||||||
|
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
|
||||||
|
|
||||||
|
if (!$sniffer.transitions) return;
|
||||||
|
|
||||||
|
ss.addRule('.entering-element.ng-enter',
|
||||||
|
'-webkit-transition:5s linear all;' +
|
||||||
|
'transition:5s linear all;');
|
||||||
|
|
||||||
|
ss.addRule('.entering-element.ng-enter-stagger',
|
||||||
|
'-webkit-transition-delay:0.5s;' +
|
||||||
|
'transition-delay:0.5s;');
|
||||||
|
|
||||||
|
element = $compile(html('<div></div>'))($rootScope);
|
||||||
|
var kids = [];
|
||||||
|
for(var i = 0; i < 5; i++) {
|
||||||
|
kids.push(angular.element('<div class="entering-element"></div>'));
|
||||||
|
$animate.enter(kids[i], element);
|
||||||
|
}
|
||||||
|
$rootScope.$digest();
|
||||||
|
|
||||||
|
$timeout.flush(10); //reflow
|
||||||
|
expect(element.children().length).toBe(5);
|
||||||
|
|
||||||
|
for(var i = 0; i < 5; i++) {
|
||||||
|
expect(kids[i].hasClass('ng-enter-active')).toBe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$timeout.flush(7500);
|
||||||
|
|
||||||
|
for(var i = 0; i < 5; i++) {
|
||||||
|
expect(kids[i].hasClass('ng-enter-active')).toBe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(stagger * index) + (duration + delay) * 150%
|
||||||
|
$timeout.flush(9500); //0.5 * 4 + 5 * 1.5 = 9500;
|
||||||
|
|
||||||
|
for(var i = 0; i < 5; i++) {
|
||||||
|
expect(kids[i].hasClass('ng-enter-active')).toBe(false);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
it("should not allow the closing animation to close off a successive animation midway",
|
it("should not allow the closing animation to close off a successive animation midway",
|
||||||
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
|
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue