fix(animation): always run before classes and functions

fixes #8842
fixes #8769
This commit is contained in:
Manu Mtz.-Almeida
2016-11-14 17:24:05 +01:00
committed by Adam Bradley
parent 217c171e5f
commit d9e9ece836

View File

@ -1,5 +1,5 @@
import { CSS, nativeRaf, transitionEnd, nativeTimeout } from '../util/dom'; import { CSS, nativeRaf, transitionEnd, nativeTimeout } from '../util/dom';
import { isDefined } from '../util/util'; import { isDefined, assert } from '../util/util';
/** /**
@ -297,7 +297,10 @@ export class Animation {
* Play the animation. * Play the animation.
*/ */
play(opts?: PlayOptions) { play(opts?: PlayOptions) {
const dur = this.getDuration(opts); // If the animation was already invalidated (it did finish), do nothing
if (!this._raf) {
return;
}
// this is the top level animation and is in full control // this is the top level animation and is in full control
// of when the async play() should actually kick off // of when the async play() should actually kick off
@ -311,22 +314,16 @@ export class Animation {
this._clearAsync(); this._clearAsync();
// recursively kicks off the correct progress step for each child animation // recursively kicks off the correct progress step for each child animation
this._playInit(opts);
if (this._isAsync) {
// for the root animation only
// set the async TRANSITION END event
// and run onFinishes when the transition ends
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._asyncEnd(dur, true); this._playInit(opts);
}
// doubling up RAFs since this animation was probably triggered // doubling up RAFs since this animation was probably triggered
// from an input event, and just having one RAF would have this code // from an input event, and just having one RAF would have this code
// run within the same frame as the triggering input event, and the // run within the same frame as the triggering input event, and the
// input event probably already did way too much work for one frame // input event probably already did way too much work for one frame
this._raf && this._raf(() => { this._raf(() => {
this._raf && this._raf(this._playDomInspect.bind(this, opts)); assert(this._raf, '_raf has to be valid');
this._raf(this._playDomInspect.bind(this, opts));
}); });
} }
@ -372,21 +369,24 @@ export class Animation {
// elements will be in the DOM, however visibily hidden // elements will be in the DOM, however visibily hidden
// so we can read their dimensions if need be // so we can read their dimensions if need be
// ******** DOM READ **************** // ******** DOM READ ****************
this._beforeReadFn();
// ******** DOM READS ABOVE / DOM WRITES BELOW ****************
// fire off all the "before" function that have DOM WRITES in them
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._beforeWriteFn(); this._beforeAnimation();
// for the root animation only
// set the async TRANSITION END event
// and run onFinishes when the transition ends
const dur = this.getDuration(opts);
if (this._isAsync) {
this._asyncEnd(dur, true);
}
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._playProgress(opts); this._playProgress(opts);
if (this._isAsync) { if (this._isAsync && this._raf) {
// this animation has a duration so we need another RAF // this animation has a duration so we need another RAF
// for the CSS TRANSITION properties to kick in // for the CSS TRANSITION properties to kick in
this._raf && this._raf(this._playToStep.bind(this, 1)); this._raf(this._playToStep.bind(this, 1));
} }
} }
@ -401,10 +401,6 @@ export class Animation {
this._c[i]._playProgress(opts); this._c[i]._playProgress(opts);
} }
// stage all of the before css classes and inline styles
// ******** DOM WRITE ****************
this._before();
if (this._hasDur) { if (this._hasDur) {
// set the CSS TRANSITION duration/easing // set the CSS TRANSITION duration/easing
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
@ -418,7 +414,7 @@ export class Animation {
// since there was no animation, immediately run the after // since there was no animation, immediately run the after
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._after(); this._afterAnimation();
// this animation has no duration, so it has finished // this animation has no duration, so it has finished
// other animations could still be running // other animations could still be running
@ -517,7 +513,7 @@ export class Animation {
// set the after styles // set the after styles
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._after(); this._afterAnimation();
// remove the will-change properties // remove the will-change properties
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
@ -684,12 +680,44 @@ export class Animation {
/** /**
* @private * @private
* DOM READ
* DOM WRITE * DOM WRITE
* NO RECURSION * RECURSION
*/ */
_before() { _beforeAnimation() {
// fire off all the "before" function that have DOM READS in them
// elements will be in the DOM, however visibily hidden
// so we can read their dimensions if need be
// ******** DOM READ ****************
this._fireBeforeReadFunc();
// ******** DOM READS ABOVE / DOM WRITES BELOW ****************
// fire off all the "before" function that have DOM WRITES in them
// ******** DOM WRITE ****************
this._fireBeforeWriteFunc();
// stage all of the before css classes and inline styles
// ******** DOM WRITE ****************
this._setBeforeStyles();
}
/**
* @private
* DOM WRITE
* RECURSION
*/
_setBeforeStyles() {
for (var i = 0; i < this._cL; i++) {
this._c[i]._setBeforeStyles();
}
// before the animations have started // before the animations have started
if (!this._rv) { // only set before styles if animation is not reversed
if (this._rv) {
return;
}
let ele: HTMLElement; let ele: HTMLElement;
for (var i = 0; i < this._eL; i++) { for (var i = 0; i < this._eL; i++) {
ele = this._e[i]; ele = this._e[i];
@ -719,17 +747,16 @@ export class Animation {
} }
} }
} }
}
/** /**
* @private * @private
* DOM READ * DOM READ
* RECURSION * RECURSION
*/ */
_beforeReadFn() { _fireBeforeReadFunc() {
for (var i = 0; i < this._cL; i++) { for (var i = 0; i < this._cL; i++) {
// ******** DOM READ **************** // ******** DOM READ ****************
this._c[i]._beforeReadFn(); this._c[i]._fireBeforeReadFunc();
} }
if (this._rdFn) { if (this._rdFn) {
@ -745,10 +772,10 @@ export class Animation {
* DOM WRITE * DOM WRITE
* RECURSION * RECURSION
*/ */
_beforeWriteFn() { _fireBeforeWriteFunc() {
for (var i = 0; i < this._cL; i++) { for (var i = 0; i < this._cL; i++) {
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._c[i]._beforeWriteFn(); this._c[i]._fireBeforeWriteFunc();
} }
if (this._wrFn) { if (this._wrFn) {
@ -762,9 +789,13 @@ export class Animation {
/** /**
* @private * @private
* DOM WRITE * DOM WRITE
* NO RECURSION * RECURSION
*/ */
_after() { _afterAnimation() {
for (var i = 0; i < this._cL; i++) {
this._c[i]._afterAnimation();
}
let ele: HTMLElement; let ele: HTMLElement;
for (var i = 0; i < this._eL; i++) { for (var i = 0; i < this._eL; i++) {
ele = this._e[i]; ele = this._e[i];
@ -828,7 +859,6 @@ export class Animation {
} }
} }
} }
} }
/** /**
@ -864,15 +894,8 @@ export class Animation {
// ensure all past transition end events have been cleared // ensure all past transition end events have been cleared
this._clearAsync(); this._clearAsync();
// fire off all the "before" function that have DOM READS in them // ******** DOM READ/WRITE ****************
// elements will be in the DOM, however visibily hidden this._beforeAnimation();
// so we can read their dimensions if need be
// ******** DOM READ ****************
this._beforeReadFn();
// fire off all the "before" function that have DOM WRITES in them
// ******** DOM WRITE ****************
this._beforeWriteFn();
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._progressStart(); this._progressStart();
@ -889,9 +912,6 @@ export class Animation {
this._c[i]._progressStart(); this._c[i]._progressStart();
} }
// ******** DOM WRITE ****************
this._before();
// force no duration, linear easing // force no duration, linear easing
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._setTrans(0, true); this._setTrans(0, true);
@ -971,7 +991,7 @@ export class Animation {
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
this._progress(stepValue); this._progress(stepValue);
this._willChg(false); this._willChg(false);
this._after(); this._afterAnimation();
this._didFinish(shouldComplete); this._didFinish(shouldComplete);
} else { } else {