UNPKG

42.9 kBJavaScriptView Raw
1import { isDefined } from '../util/util';
2/**
3 * @hidden
4 */
5var Animation = (function () {
6 /**
7 * @param {?} plt
8 * @param {?=} ele
9 * @param {?=} opts
10 */
11 function Animation(plt, ele, opts) {
12 this._dur = null;
13 this._es = null;
14 this._rvEs = null;
15 this.hasChildren = false;
16 this.isPlaying = false;
17 this.hasCompleted = false;
18 this.plt = plt;
19 this.element(ele);
20 this.opts = opts;
21 }
22 /**
23 * @param {?} ele
24 * @return {?}
25 */
26 Animation.prototype.element = function (ele) {
27 if (ele) {
28 if (typeof ele === 'string') {
29 ele = this.plt.doc().querySelectorAll(ele);
30 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
31 this._addEle(ele[i]);
32 }
33 }
34 else if (ele.length) {
35 for (var /** @type {?} */ i = 0; i < ele.length; i++) {
36 this._addEle(ele[i]);
37 }
38 }
39 else {
40 this._addEle(ele);
41 }
42 }
43 return this;
44 };
45 /**
46 * NO DOM
47 * @param {?} ele
48 * @return {?}
49 */
50 Animation.prototype._addEle = function (ele) {
51 if (ele.nativeElement) {
52 ele = ele.nativeElement;
53 }
54 if (((ele)).nodeType === 1) {
55 this._eL = (this._e = this._e || []).push(ele);
56 }
57 };
58 /**
59 * Add a child animation to this animation.
60 * @param {?} childAnimation
61 * @return {?}
62 */
63 Animation.prototype.add = function (childAnimation) {
64 childAnimation.parent = this;
65 this.hasChildren = true;
66 this._cL = (this._c = this._c || []).push(childAnimation);
67 return this;
68 };
69 /**
70 * Get the duration of this animation. If this animation does
71 * not have a duration, then it'll get the duration from its parent.
72 * @param {?=} opts
73 * @return {?}
74 */
75 Animation.prototype.getDuration = function (opts) {
76 if (opts && isDefined(opts.duration)) {
77 return opts.duration;
78 }
79 else if (this._dur !== null) {
80 return this._dur;
81 }
82 else if (this.parent) {
83 return this.parent.getDuration();
84 }
85 return 0;
86 };
87 /**
88 * Returns if the animation is a root one.
89 * @return {?}
90 */
91 Animation.prototype.isRoot = function () {
92 return !this.parent;
93 };
94 /**
95 * Set the duration for this animation.
96 * @param {?} milliseconds
97 * @return {?}
98 */
99 Animation.prototype.duration = function (milliseconds) {
100 this._dur = milliseconds;
101 return this;
102 };
103 /**
104 * Get the easing of this animation. If this animation does
105 * not have an easing, then it'll get the easing from its parent.
106 * @return {?}
107 */
108 Animation.prototype.getEasing = function () {
109 if (this._rv && this._rvEs) {
110 return this._rvEs;
111 }
112 return this._es !== null ? this._es : (this.parent && this.parent.getEasing()) || null;
113 };
114 /**
115 * Set the easing for this animation.
116 * @param {?} name
117 * @return {?}
118 */
119 Animation.prototype.easing = function (name) {
120 this._es = name;
121 return this;
122 };
123 /**
124 * Set the easing for this reversed animation.
125 * @param {?} name
126 * @return {?}
127 */
128 Animation.prototype.easingReverse = function (name) {
129 this._rvEs = name;
130 return this;
131 };
132 /**
133 * Add the "from" value for a specific property.
134 * @param {?} prop
135 * @param {?} val
136 * @return {?}
137 */
138 Animation.prototype.from = function (prop, val) {
139 this._addProp('from', prop, val);
140 return this;
141 };
142 /**
143 * Add the "to" value for a specific property.
144 * @param {?} prop
145 * @param {?} val
146 * @param {?=} clearProperyAfterTransition
147 * @return {?}
148 */
149 Animation.prototype.to = function (prop, val, clearProperyAfterTransition) {
150 var /** @type {?} */ fx = this._addProp('to', prop, val);
151 if (clearProperyAfterTransition) {
152 // if this effect is a transform then clear the transform effect
153 // otherwise just clear the actual property
154 this.afterClearStyles([fx.trans ? this.plt.Css.transform : prop]);
155 }
156 return this;
157 };
158 /**
159 * Shortcut to add both the "from" and "to" for the same property.
160 * @param {?} prop
161 * @param {?} fromVal
162 * @param {?} toVal
163 * @param {?=} clearProperyAfterTransition
164 * @return {?}
165 */
166 Animation.prototype.fromTo = function (prop, fromVal, toVal, clearProperyAfterTransition) {
167 return this.from(prop, fromVal).to(prop, toVal, clearProperyAfterTransition);
168 };
169 /**
170 * @hidden
171 * NO DOM
172 * @param {?} name
173 * @return {?}
174 */
175 Animation.prototype._getProp = function (name) {
176 if (this._fx) {
177 return this._fx.find(function (prop) { return prop.name === name; });
178 }
179 else {
180 this._fx = [];
181 }
182 return null;
183 };
184 /**
185 * @param {?} state
186 * @param {?} prop
187 * @param {?} val
188 * @return {?}
189 */
190 Animation.prototype._addProp = function (state, prop, val) {
191 var /** @type {?} */ fxProp = this._getProp(prop);
192 if (!fxProp) {
193 // first time we've see this EffectProperty
194 var /** @type {?} */ shouldTrans = (ANIMATION_TRANSFORMS[prop] === 1);
195 fxProp = {
196 name: prop,
197 trans: shouldTrans,
198 // add the will-change property for transforms or opacity
199 wc: (shouldTrans ? this.plt.Css.transform : prop)
200 };
201 this._fx.push(fxProp);
202 }
203 // add from/to EffectState to the EffectProperty
204 var /** @type {?} */ fxState = {
205 val: val,
206 num: null,
207 unit: '',
208 };
209 fxProp[state] = fxState;
210 if (typeof val === 'string' && val.indexOf(' ') < 0) {
211 var /** @type {?} */ r = val.match(ANIMATION_CSS_VALUE_REGEX);
212 var /** @type {?} */ num = parseFloat(r[1]);
213 if (!isNaN(num)) {
214 fxState.num = num;
215 }
216 fxState.unit = (r[0] !== r[2] ? r[2] : '');
217 }
218 else if (typeof val === 'number') {
219 fxState.num = val;
220 }
221 return fxProp;
222 };
223 /**
224 * Add CSS class to this animation's elements
225 * before the animation begins.
226 * @param {?} className
227 * @return {?}
228 */
229 Animation.prototype.beforeAddClass = function (className) {
230 (this._bfAdd = this._bfAdd || []).push(className);
231 return this;
232 };
233 /**
234 * Remove CSS class from this animation's elements
235 * before the animation begins.
236 * @param {?} className
237 * @return {?}
238 */
239 Animation.prototype.beforeRemoveClass = function (className) {
240 (this._bfRm = this._bfRm || []).push(className);
241 return this;
242 };
243 /**
244 * Set CSS inline styles to this animation's elements
245 * before the animation begins.
246 * @param {?} styles
247 * @return {?}
248 */
249 Animation.prototype.beforeStyles = function (styles) {
250 this._bfSty = styles;
251 return this;
252 };
253 /**
254 * Clear CSS inline styles from this animation's elements
255 * before the animation begins.
256 * @param {?} propertyNames
257 * @return {?}
258 */
259 Animation.prototype.beforeClearStyles = function (propertyNames) {
260 this._bfSty = this._bfSty || {};
261 for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
262 this._bfSty[propertyNames[i]] = '';
263 }
264 return this;
265 };
266 /**
267 * Add a function which contains DOM reads, which will run
268 * before the animation begins.
269 * @param {?} domReadFn
270 * @return {?}
271 */
272 Animation.prototype.beforeAddRead = function (domReadFn) {
273 (this._rdFn = this._rdFn || []).push(domReadFn);
274 return this;
275 };
276 /**
277 * Add a function which contains DOM writes, which will run
278 * before the animation begins.
279 * @param {?} domWriteFn
280 * @return {?}
281 */
282 Animation.prototype.beforeAddWrite = function (domWriteFn) {
283 (this._wrFn = this._wrFn || []).push(domWriteFn);
284 return this;
285 };
286 /**
287 * Add CSS class to this animation's elements
288 * after the animation finishes.
289 * @param {?} className
290 * @return {?}
291 */
292 Animation.prototype.afterAddClass = function (className) {
293 (this._afAdd = this._afAdd || []).push(className);
294 return this;
295 };
296 /**
297 * Remove CSS class from this animation's elements
298 * after the animation finishes.
299 * @param {?} className
300 * @return {?}
301 */
302 Animation.prototype.afterRemoveClass = function (className) {
303 (this._afRm = this._afRm || []).push(className);
304 return this;
305 };
306 /**
307 * Set CSS inline styles to this animation's elements
308 * after the animation finishes.
309 * @param {?} styles
310 * @return {?}
311 */
312 Animation.prototype.afterStyles = function (styles) {
313 this._afSty = styles;
314 return this;
315 };
316 /**
317 * Clear CSS inline styles from this animation's elements
318 * after the animation finishes.
319 * @param {?} propertyNames
320 * @return {?}
321 */
322 Animation.prototype.afterClearStyles = function (propertyNames) {
323 this._afSty = this._afSty || {};
324 for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
325 this._afSty[propertyNames[i]] = '';
326 }
327 return this;
328 };
329 /**
330 * Play the animation.
331 * @param {?=} opts
332 * @return {?}
333 */
334 Animation.prototype.play = function (opts) {
335 var _this = this;
336 // If the animation was already invalidated (it did finish), do nothing
337 if (!this.plt) {
338 return;
339 }
340 // this is the top level animation and is in full control
341 // of when the async play() should actually kick off
342 // if there is no duration then it'll set the TO property immediately
343 // if there is a duration, then it'll stage all animations at the
344 // FROM property and transition duration, wait a few frames, then
345 // kick off the animation by setting the TO property for each animation
346 this._isAsync = this._hasDuration(opts);
347 // ensure all past transition end events have been cleared
348 this._clearAsync();
349 // recursively kicks off the correct progress step for each child animation
350 // ******** DOM WRITE ****************
351 this._playInit(opts);
352 // doubling up RAFs since this animation was probably triggered
353 // from an input event, and just having one RAF would have this code
354 // run within the same frame as the triggering input event, and the
355 // input event probably already did way too much work for one frame
356 this.plt.raf(function () {
357 _this.plt.raf(_this._playDomInspect.bind(_this, opts));
358 });
359 };
360 /**
361 * @return {?}
362 */
363 Animation.prototype.syncPlay = function () {
364 // If the animation was already invalidated (it did finish), do nothing
365 if (!this.plt) {
366 return;
367 }
368 var /** @type {?} */ opts = { duration: 0 };
369 this._isAsync = false;
370 this._clearAsync();
371 this._playInit(opts);
372 this._playDomInspect(opts);
373 };
374 /**
375 * @hidden
376 * DOM WRITE
377 * RECURSION
378 * @param {?} opts
379 * @return {?}
380 */
381 Animation.prototype._playInit = function (opts) {
382 // always default that an animation does not tween
383 // a tween requires that an Animation class has an element
384 // and that it has at least one FROM/TO effect
385 // and that the FROM/TO effect can tween numeric values
386 this._twn = false;
387 this.isPlaying = true;
388 this.hasCompleted = false;
389 this._hasDur = (this.getDuration(opts) > ANIMATION_DURATION_MIN);
390 var /** @type {?} */ children = this._c;
391 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
392 // ******** DOM WRITE ****************
393 children[i]._playInit(opts);
394 }
395 if (this._hasDur) {
396 // if there is a duration then we want to start at step 0
397 // ******** DOM WRITE ****************
398 this._progress(0);
399 // add the will-change properties
400 // ******** DOM WRITE ****************
401 this._willChg(true);
402 }
403 };
404 /**
405 * @hidden
406 * DOM WRITE
407 * NO RECURSION
408 * ROOT ANIMATION
409 * @param {?} opts
410 * @return {?}
411 */
412 Animation.prototype._playDomInspect = function (opts) {
413 // fire off all the "before" function that have DOM READS in them
414 // elements will be in the DOM, however visibily hidden
415 // so we can read their dimensions if need be
416 // ******** DOM READ ****************
417 // ******** DOM WRITE ****************
418 this._beforeAnimation();
419 // for the root animation only
420 // set the async TRANSITION END event
421 // and run onFinishes when the transition ends
422 var /** @type {?} */ dur = this.getDuration(opts);
423 if (this._isAsync) {
424 this._asyncEnd(dur, true);
425 }
426 // ******** DOM WRITE ****************
427 this._playProgress(opts);
428 if (this._isAsync && this.plt) {
429 // this animation has a duration so we need another RAF
430 // for the CSS TRANSITION properties to kick in
431 this.plt.raf(this._playToStep.bind(this, 1));
432 }
433 };
434 /**
435 * @hidden
436 * DOM WRITE
437 * RECURSION
438 * @param {?} opts
439 * @return {?}
440 */
441 Animation.prototype._playProgress = function (opts) {
442 var /** @type {?} */ children = this._c;
443 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
444 // ******** DOM WRITE ****************
445 children[i]._playProgress(opts);
446 }
447 if (this._hasDur) {
448 // set the CSS TRANSITION duration/easing
449 // ******** DOM WRITE ****************
450 this._setTrans(this.getDuration(opts), false);
451 }
452 else {
453 // this animation does not have a duration, so it should not animate
454 // just go straight to the TO properties and call it done
455 // ******** DOM WRITE ****************
456 this._progress(1);
457 // since there was no animation, immediately run the after
458 // ******** DOM WRITE ****************
459 this._setAfterStyles();
460 // this animation has no duration, so it has finished
461 // other animations could still be running
462 this._didFinish(true);
463 }
464 };
465 /**
466 * @hidden
467 * DOM WRITE
468 * RECURSION
469 * @param {?} stepValue
470 * @return {?}
471 */
472 Animation.prototype._playToStep = function (stepValue) {
473 var /** @type {?} */ children = this._c;
474 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
475 // ******** DOM WRITE ****************
476 children[i]._playToStep(stepValue);
477 }
478 if (this._hasDur) {
479 // browser had some time to render everything in place
480 // and the transition duration/easing is set
481 // now set the TO properties which will trigger the transition to begin
482 // ******** DOM WRITE ****************
483 this._progress(stepValue);
484 }
485 };
486 /**
487 * @hidden
488 * DOM WRITE
489 * NO RECURSION
490 * ROOT ANIMATION
491 * @param {?} dur
492 * @param {?} shouldComplete
493 * @return {?}
494 */
495 Animation.prototype._asyncEnd = function (dur, shouldComplete) {
496 (void 0) /* assert */;
497 (void 0) /* assert */;
498 (void 0) /* assert */;
499 var /** @type {?} */ self = this;
500 /**
501 * @return {?}
502 */
503 function onTransitionEnd() {
504 // congrats! a successful transition completed!
505 // ensure transition end events and timeouts have been cleared
506 self._clearAsync();
507 // ******** DOM WRITE ****************
508 self._playEnd();
509 // transition finished
510 self._didFinishAll(shouldComplete, true, false);
511 }
512 /**
513 * @return {?}
514 */
515 function onTransitionFallback() {
516 (void 0) /* console.debug */;
517 // oh noz! the transition end event didn't fire in time!
518 // instead the fallback timer when first
519 // if all goes well this fallback should never fire
520 // clear the other async end events from firing
521 self._tm = undefined;
522 self._clearAsync();
523 // set the after styles
524 // ******** DOM WRITE ****************
525 self._playEnd(shouldComplete ? 1 : 0);
526 // transition finished
527 self._didFinishAll(shouldComplete, true, false);
528 }
529 // set the TRANSITION END event on one of the transition elements
530 self._unrgTrns = this.plt.transitionEnd(self._transEl(), onTransitionEnd, false);
531 // set a fallback timeout if the transition end event never fires, or is too slow
532 // transition end fallback: (animation duration + XXms)
533 self._tm = self.plt.timeout(onTransitionFallback, (dur + ANIMATION_TRANSITION_END_FALLBACK_PADDING_MS));
534 };
535 /**
536 * @hidden
537 * DOM WRITE
538 * RECURSION
539 * @param {?=} stepValue
540 * @return {?}
541 */
542 Animation.prototype._playEnd = function (stepValue) {
543 var /** @type {?} */ children = this._c;
544 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
545 // ******** DOM WRITE ****************
546 children[i]._playEnd(stepValue);
547 }
548 if (this._hasDur) {
549 if (isDefined(stepValue)) {
550 // too late to have a smooth animation, just finish it
551 // ******** DOM WRITE ****************
552 this._setTrans(0, true);
553 // ensure the ending progress step gets rendered
554 // ******** DOM WRITE ****************
555 this._progress(stepValue);
556 }
557 // set the after styles
558 // ******** DOM WRITE ****************
559 this._setAfterStyles();
560 // remove the will-change properties
561 // ******** DOM WRITE ****************
562 this._willChg(false);
563 }
564 };
565 /**
566 * @hidden
567 * NO DOM
568 * RECURSION
569 * @param {?} opts
570 * @return {?}
571 */
572 Animation.prototype._hasDuration = function (opts) {
573 if (this.getDuration(opts) > ANIMATION_DURATION_MIN) {
574 return true;
575 }
576 var /** @type {?} */ children = this._c;
577 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
578 if (children[i]._hasDuration(opts)) {
579 return true;
580 }
581 }
582 return false;
583 };
584 /**
585 * @hidden
586 * NO DOM
587 * RECURSION
588 * @return {?}
589 */
590 Animation.prototype._hasDomReads = function () {
591 if (this._rdFn && this._rdFn.length) {
592 return true;
593 }
594 var /** @type {?} */ children = this._c;
595 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
596 if (children[i]._hasDomReads()) {
597 return true;
598 }
599 }
600 return false;
601 };
602 /**
603 * Immediately stop at the end of the animation.
604 * @param {?=} stepValue
605 * @return {?}
606 */
607 Animation.prototype.stop = function (stepValue) {
608 if (stepValue === void 0) { stepValue = 1; }
609 // ensure all past transition end events have been cleared
610 this._clearAsync();
611 this._hasDur = true;
612 this._playEnd(stepValue);
613 };
614 /**
615 * @hidden
616 * NO DOM
617 * NO RECURSION
618 * @return {?}
619 */
620 Animation.prototype._clearAsync = function () {
621 this._unrgTrns && this._unrgTrns();
622 this._tm && clearTimeout(this._tm);
623 this._tm = this._unrgTrns = undefined;
624 };
625 /**
626 * @hidden
627 * DOM WRITE
628 * NO RECURSION
629 * @param {?} stepValue
630 * @return {?}
631 */
632 Animation.prototype._progress = function (stepValue) {
633 // bread 'n butter
634 var /** @type {?} */ val;
635 var /** @type {?} */ effects = this._fx;
636 var /** @type {?} */ nuElements = this._eL;
637 if (!effects || !nuElements) {
638 return;
639 }
640 // flip the number if we're going in reverse
641 if (this._rv) {
642 stepValue = ((stepValue * -1) + 1);
643 }
644 var /** @type {?} */ i, /** @type {?} */ j;
645 var /** @type {?} */ finalTransform = '';
646 var /** @type {?} */ elements = this._e;
647 for (i = 0; i < effects.length; i++) {
648 var /** @type {?} */ fx = effects[i];
649 if (fx.from && fx.to) {
650 var /** @type {?} */ fromNum = fx.from.num;
651 var /** @type {?} */ toNum = fx.to.num;
652 var /** @type {?} */ tweenEffect = (fromNum !== toNum);
653 (void 0) /* assert */;
654 if (tweenEffect) {
655 this._twn = true;
656 }
657 if (stepValue === 0) {
658 // FROM
659 val = fx.from.val;
660 }
661 else if (stepValue === 1) {
662 // TO
663 val = fx.to.val;
664 }
665 else if (tweenEffect) {
666 // EVERYTHING IN BETWEEN
667 var /** @type {?} */ valNum = (((toNum - fromNum) * stepValue) + fromNum);
668 var /** @type {?} */ unit = fx.to.unit;
669 if (unit === 'px') {
670 valNum = Math.round(valNum);
671 }
672 val = valNum + unit;
673 }
674 if (val !== null) {
675 var /** @type {?} */ prop = fx.name;
676 if (fx.trans) {
677 finalTransform += prop + '(' + val + ') ';
678 }
679 else {
680 for (j = 0; j < nuElements; j++) {
681 // ******** DOM WRITE ****************
682 ((elements[j].style))[prop] = val;
683 }
684 }
685 }
686 }
687 }
688 // place all transforms on the same property
689 if (finalTransform.length) {
690 if (!this._rv && stepValue !== 1 || this._rv && stepValue !== 0) {
691 finalTransform += 'translateZ(0px)';
692 }
693 var /** @type {?} */ cssTransform = this.plt.Css.transform;
694 for (i = 0; i < elements.length; i++) {
695 // ******** DOM WRITE ****************
696 ((elements[i].style))[cssTransform] = finalTransform;
697 }
698 }
699 };
700 /**
701 * @hidden
702 * DOM WRITE
703 * NO RECURSION
704 * @param {?} dur
705 * @param {?} forcedLinearEasing
706 * @return {?}
707 */
708 Animation.prototype._setTrans = function (dur, forcedLinearEasing) {
709 // Transition is not enabled if there are not effects
710 if (!this._fx) {
711 return;
712 }
713 // set the TRANSITION properties inline on the element
714 var /** @type {?} */ elements = this._e;
715 var /** @type {?} */ easing = (forcedLinearEasing ? 'linear' : this.getEasing());
716 var /** @type {?} */ durString = dur + 'ms';
717 var /** @type {?} */ Css = this.plt.Css;
718 var /** @type {?} */ cssTransform = Css.transition;
719 var /** @type {?} */ cssTransitionDuration = Css.transitionDuration;
720 var /** @type {?} */ cssTransitionTimingFn = Css.transitionTimingFn;
721 var /** @type {?} */ eleStyle;
722 for (var /** @type {?} */ i = 0; i < this._eL; i++) {
723 eleStyle = elements[i].style;
724 if (dur > 0) {
725 // ******** DOM WRITE ****************
726 eleStyle[cssTransform] = '';
727 eleStyle[cssTransitionDuration] = durString;
728 // each animation can have a different easing
729 if (easing) {
730 // ******** DOM WRITE ****************
731 eleStyle[cssTransitionTimingFn] = easing;
732 }
733 }
734 else {
735 eleStyle[cssTransform] = 'none';
736 }
737 }
738 };
739 /**
740 * @hidden
741 * DOM READ
742 * DOM WRITE
743 * RECURSION
744 * @return {?}
745 */
746 Animation.prototype._beforeAnimation = function () {
747 // fire off all the "before" function that have DOM READS in them
748 // elements will be in the DOM, however visibily hidden
749 // so we can read their dimensions if need be
750 // ******** DOM READ ****************
751 this._fireBeforeReadFunc();
752 // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
753 // fire off all the "before" function that have DOM WRITES in them
754 // ******** DOM WRITE ****************
755 this._fireBeforeWriteFunc();
756 // stage all of the before css classes and inline styles
757 // ******** DOM WRITE ****************
758 this._setBeforeStyles();
759 };
760 /**
761 * @hidden
762 * DOM WRITE
763 * RECURSION
764 * @return {?}
765 */
766 Animation.prototype._setBeforeStyles = function () {
767 var /** @type {?} */ i, /** @type {?} */ j;
768 var /** @type {?} */ children = this._c;
769 for (i = 0; i < this._cL; i++) {
770 children[i]._setBeforeStyles();
771 }
772 // before the animations have started
773 // only set before styles if animation is not reversed
774 if (this._rv) {
775 return;
776 }
777 var /** @type {?} */ addClasses = this._bfAdd;
778 var /** @type {?} */ removeClasses = this._bfRm;
779 var /** @type {?} */ ele;
780 var /** @type {?} */ eleClassList;
781 var /** @type {?} */ prop;
782 for (i = 0; i < this._eL; i++) {
783 ele = this._e[i];
784 eleClassList = ele.classList;
785 // css classes to add before the animation
786 if (addClasses) {
787 for (j = 0; j < addClasses.length; j++) {
788 // ******** DOM WRITE ****************
789 eleClassList.add(addClasses[j]);
790 }
791 }
792 // css classes to remove before the animation
793 if (removeClasses) {
794 for (j = 0; j < removeClasses.length; j++) {
795 // ******** DOM WRITE ****************
796 eleClassList.remove(removeClasses[j]);
797 }
798 }
799 // inline styles to add before the animation
800 if (this._bfSty) {
801 for (prop in this._bfSty) {
802 // ******** DOM WRITE ****************
803 ((ele)).style[prop] = this._bfSty[prop];
804 }
805 }
806 }
807 };
808 /**
809 * @hidden
810 * DOM READ
811 * RECURSION
812 * @return {?}
813 */
814 Animation.prototype._fireBeforeReadFunc = function () {
815 var /** @type {?} */ children = this._c;
816 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
817 // ******** DOM READ ****************
818 children[i]._fireBeforeReadFunc();
819 }
820 var /** @type {?} */ readFunctions = this._rdFn;
821 if (readFunctions) {
822 for (var /** @type {?} */ i = 0; i < readFunctions.length; i++) {
823 // ******** DOM READ ****************
824 readFunctions[i]();
825 }
826 }
827 };
828 /**
829 * @hidden
830 * DOM WRITE
831 * RECURSION
832 * @return {?}
833 */
834 Animation.prototype._fireBeforeWriteFunc = function () {
835 var /** @type {?} */ children = this._c;
836 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
837 // ******** DOM WRITE ****************
838 children[i]._fireBeforeWriteFunc();
839 }
840 var /** @type {?} */ writeFunctions = this._wrFn;
841 if (this._wrFn) {
842 for (var /** @type {?} */ i = 0; i < writeFunctions.length; i++) {
843 // ******** DOM WRITE ****************
844 writeFunctions[i]();
845 }
846 }
847 };
848 /**
849 * @hidden
850 * DOM WRITE
851 * @return {?}
852 */
853 Animation.prototype._setAfterStyles = function () {
854 var /** @type {?} */ i, /** @type {?} */ j;
855 var /** @type {?} */ ele;
856 var /** @type {?} */ eleClassList;
857 var /** @type {?} */ elements = this._e;
858 for (i = 0; i < this._eL; i++) {
859 ele = elements[i];
860 eleClassList = ele.classList;
861 // remove the transition duration/easing
862 // ******** DOM WRITE ****************
863 ((ele)).style[this.plt.Css.transitionDuration] = ((ele)).style[this.plt.Css.transitionTimingFn] = '';
864 if (this._rv) {
865 // finished in reverse direction
866 // css classes that were added before the animation should be removed
867 if (this._bfAdd) {
868 for (j = 0; j < this._bfAdd.length; j++) {
869 // ******** DOM WRITE ****************
870 eleClassList.remove(this._bfAdd[j]);
871 }
872 }
873 // css classes that were removed before the animation should be added
874 if (this._bfRm) {
875 for (j = 0; j < this._bfRm.length; j++) {
876 // ******** DOM WRITE ****************
877 eleClassList.add(this._bfRm[j]);
878 }
879 }
880 // inline styles that were added before the animation should be removed
881 if (this._bfSty) {
882 for (var /** @type {?} */ prop in this._bfSty) {
883 // ******** DOM WRITE ****************
884 ((ele)).style[prop] = '';
885 }
886 }
887 }
888 else {
889 // finished in forward direction
890 // css classes to add after the animation
891 if (this._afAdd) {
892 for (j = 0; j < this._afAdd.length; j++) {
893 // ******** DOM WRITE ****************
894 eleClassList.add(this._afAdd[j]);
895 }
896 }
897 // css classes to remove after the animation
898 if (this._afRm) {
899 for (j = 0; j < this._afRm.length; j++) {
900 // ******** DOM WRITE ****************
901 eleClassList.remove(this._afRm[j]);
902 }
903 }
904 // inline styles to add after the animation
905 if (this._afSty) {
906 for (var /** @type {?} */ prop in this._afSty) {
907 // ******** DOM WRITE ****************
908 ((ele)).style[prop] = this._afSty[prop];
909 }
910 }
911 }
912 }
913 };
914 /**
915 * @hidden
916 * DOM WRITE
917 * NO RECURSION
918 * @param {?} addWillChange
919 * @return {?}
920 */
921 Animation.prototype._willChg = function (addWillChange) {
922 var /** @type {?} */ wc;
923 var /** @type {?} */ effects = this._fx;
924 var /** @type {?} */ willChange;
925 if (addWillChange && effects) {
926 wc = [];
927 for (var /** @type {?} */ i = 0; i < effects.length; i++) {
928 var /** @type {?} */ propWC = effects[i].wc;
929 if (propWC === 'webkitTransform') {
930 wc.push('transform', '-webkit-transform');
931 }
932 else {
933 wc.push(propWC);
934 }
935 }
936 willChange = wc.join(',');
937 }
938 else {
939 willChange = '';
940 }
941 for (var /** @type {?} */ i = 0; i < this._eL; i++) {
942 // ******** DOM WRITE ****************
943 ((this._e[i])).style.willChange = willChange;
944 }
945 };
946 /**
947 * Start the animation with a user controlled progress.
948 * @return {?}
949 */
950 Animation.prototype.progressStart = function () {
951 // ensure all past transition end events have been cleared
952 this._clearAsync();
953 // ******** DOM READ/WRITE ****************
954 this._beforeAnimation();
955 // ******** DOM WRITE ****************
956 this._progressStart();
957 };
958 /**
959 * @hidden
960 * DOM WRITE
961 * RECURSION
962 * @return {?}
963 */
964 Animation.prototype._progressStart = function () {
965 var /** @type {?} */ children = this._c;
966 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
967 // ******** DOM WRITE ****************
968 children[i]._progressStart();
969 }
970 // force no duration, linear easing
971 // ******** DOM WRITE ****************
972 this._setTrans(0, true);
973 // ******** DOM WRITE ****************
974 this._willChg(true);
975 };
976 /**
977 * Set the progress step for this animation.
978 * progressStep() is not debounced, so it should not be called faster than 60FPS.
979 * @param {?} stepValue
980 * @return {?}
981 */
982 Animation.prototype.progressStep = function (stepValue) {
983 // only update if the last update was more than 16ms ago
984 stepValue = Math.min(1, Math.max(0, stepValue));
985 var /** @type {?} */ children = this._c;
986 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
987 // ******** DOM WRITE ****************
988 children[i].progressStep(stepValue);
989 }
990 if (this._rv) {
991 // if the animation is going in reverse then
992 // flip the step value: 0 becomes 1, 1 becomes 0
993 stepValue = ((stepValue * -1) + 1);
994 }
995 // ******** DOM WRITE ****************
996 this._progress(stepValue);
997 };
998 /**
999 * End the progress animation.
1000 * @param {?} shouldComplete
1001 * @param {?} currentStepValue
1002 * @param {?=} dur
1003 * @return {?}
1004 */
1005 Animation.prototype.progressEnd = function (shouldComplete, currentStepValue, dur) {
1006 if (dur === void 0) { dur = -1; }
1007 (void 0) /* console.debug */;
1008 if (this._rv) {
1009 // if the animation is going in reverse then
1010 // flip the step value: 0 becomes 1, 1 becomes 0
1011 currentStepValue = ((currentStepValue * -1) + 1);
1012 }
1013 var /** @type {?} */ stepValue = shouldComplete ? 1 : 0;
1014 var /** @type {?} */ diff = Math.abs(currentStepValue - stepValue);
1015 if (diff < 0.05) {
1016 dur = 0;
1017 }
1018 else if (dur < 0) {
1019 dur = this._dur;
1020 }
1021 this._isAsync = (dur > 30);
1022 this._progressEnd(shouldComplete, stepValue, dur, this._isAsync);
1023 if (this._isAsync) {
1024 // for the root animation only
1025 // set the async TRANSITION END event
1026 // and run onFinishes when the transition ends
1027 // ******** DOM WRITE ****************
1028 this._asyncEnd(dur, shouldComplete);
1029 // this animation has a duration so we need another RAF
1030 // for the CSS TRANSITION properties to kick in
1031 this.plt && this.plt.raf(this._playToStep.bind(this, stepValue));
1032 }
1033 };
1034 /**
1035 * @hidden
1036 * DOM WRITE
1037 * RECURSION
1038 * @param {?} shouldComplete
1039 * @param {?} stepValue
1040 * @param {?} dur
1041 * @param {?} isAsync
1042 * @return {?}
1043 */
1044 Animation.prototype._progressEnd = function (shouldComplete, stepValue, dur, isAsync) {
1045 var /** @type {?} */ children = this._c;
1046 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
1047 // ******** DOM WRITE ****************
1048 children[i]._progressEnd(shouldComplete, stepValue, dur, isAsync);
1049 }
1050 if (!isAsync) {
1051 // stop immediately
1052 // set all the animations to their final position
1053 // ******** DOM WRITE ****************
1054 this._progress(stepValue);
1055 this._willChg(false);
1056 this._setAfterStyles();
1057 this._didFinish(shouldComplete);
1058 }
1059 else {
1060 // animate it back to it's ending position
1061 this.isPlaying = true;
1062 this.hasCompleted = false;
1063 this._hasDur = true;
1064 // ******** DOM WRITE ****************
1065 this._willChg(true);
1066 this._setTrans(dur, false);
1067 }
1068 };
1069 /**
1070 * Add a callback to fire when the animation has finished.
1071 * @param {?} callback
1072 * @param {?=} onceTimeCallback
1073 * @param {?=} clearOnFinishCallacks
1074 * @return {?}
1075 */
1076 Animation.prototype.onFinish = function (callback, onceTimeCallback, clearOnFinishCallacks) {
1077 if (onceTimeCallback === void 0) { onceTimeCallback = false; }
1078 if (clearOnFinishCallacks === void 0) { clearOnFinishCallacks = false; }
1079 if (clearOnFinishCallacks) {
1080 this._fFn = this._fOneFn = undefined;
1081 }
1082 if (onceTimeCallback) {
1083 this._fOneFn = this._fOneFn || [];
1084 this._fOneFn.push(callback);
1085 }
1086 else {
1087 this._fFn = this._fFn || [];
1088 this._fFn.push(callback);
1089 }
1090 return this;
1091 };
1092 /**
1093 * @hidden
1094 * NO DOM
1095 * RECURSION
1096 * @param {?} hasCompleted
1097 * @param {?} finishAsyncAnimations
1098 * @param {?} finishNoDurationAnimations
1099 * @return {?}
1100 */
1101 Animation.prototype._didFinishAll = function (hasCompleted, finishAsyncAnimations, finishNoDurationAnimations) {
1102 var /** @type {?} */ children = this._c;
1103 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
1104 children[i]._didFinishAll(hasCompleted, finishAsyncAnimations, finishNoDurationAnimations);
1105 }
1106 if (finishAsyncAnimations && this._isAsync || finishNoDurationAnimations && !this._isAsync) {
1107 this._didFinish(hasCompleted);
1108 }
1109 };
1110 /**
1111 * @hidden
1112 * NO RECURSION
1113 * @param {?} hasCompleted
1114 * @return {?}
1115 */
1116 Animation.prototype._didFinish = function (hasCompleted) {
1117 this.isPlaying = false;
1118 this.hasCompleted = hasCompleted;
1119 if (this._fFn) {
1120 // run all finish callbacks
1121 for (var /** @type {?} */ i = 0; i < this._fFn.length; i++) {
1122 this._fFn[i](this);
1123 }
1124 }
1125 if (this._fOneFn) {
1126 // run all "onetime" finish callbacks
1127 for (var /** @type {?} */ i = 0; i < this._fOneFn.length; i++) {
1128 this._fOneFn[i](this);
1129 }
1130 this._fOneFn.length = 0;
1131 }
1132 };
1133 /**
1134 * Reverse the animation.
1135 * @param {?=} shouldReverse
1136 * @return {?}
1137 */
1138 Animation.prototype.reverse = function (shouldReverse) {
1139 if (shouldReverse === void 0) { shouldReverse = true; }
1140 var /** @type {?} */ children = this._c;
1141 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
1142 children[i].reverse(shouldReverse);
1143 }
1144 this._rv = shouldReverse;
1145 return this;
1146 };
1147 /**
1148 * Recursively destroy this animation and all child animations.
1149 * @return {?}
1150 */
1151 Animation.prototype.destroy = function () {
1152 var /** @type {?} */ children = this._c;
1153 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
1154 children[i].destroy();
1155 }
1156 this._clearAsync();
1157 this.parent = this.plt = this._e = this._rdFn = this._wrFn = null;
1158 if (this._c) {
1159 this._c.length = this._cL = 0;
1160 }
1161 if (this._fFn) {
1162 this._fFn.length = 0;
1163 }
1164 if (this._fOneFn) {
1165 this._fOneFn.length = 0;
1166 }
1167 };
1168 /**
1169 * @hidden
1170 * NO DOM
1171 * @return {?}
1172 */
1173 Animation.prototype._transEl = function () {
1174 // get the lowest level element that has an Animation
1175 var /** @type {?} */ targetEl;
1176 for (var /** @type {?} */ i = 0; i < this._cL; i++) {
1177 targetEl = this._c[i]._transEl();
1178 if (targetEl) {
1179 return targetEl;
1180 }
1181 }
1182 return (this._twn && this._hasDur && this._eL ? this._e[0] : null);
1183 };
1184 return Animation;
1185}());
1186export { Animation };
1187function Animation_tsickle_Closure_declarations() {
1188 /** @type {?} */
1189 Animation.prototype._c;
1190 /** @type {?} */
1191 Animation.prototype._cL;
1192 /** @type {?} */
1193 Animation.prototype._e;
1194 /** @type {?} */
1195 Animation.prototype._eL;
1196 /** @type {?} */
1197 Animation.prototype._fx;
1198 /** @type {?} */
1199 Animation.prototype._dur;
1200 /** @type {?} */
1201 Animation.prototype._es;
1202 /** @type {?} */
1203 Animation.prototype._rvEs;
1204 /** @type {?} */
1205 Animation.prototype._bfSty;
1206 /** @type {?} */
1207 Animation.prototype._bfAdd;
1208 /** @type {?} */
1209 Animation.prototype._bfRm;
1210 /** @type {?} */
1211 Animation.prototype._afSty;
1212 /** @type {?} */
1213 Animation.prototype._afAdd;
1214 /** @type {?} */
1215 Animation.prototype._afRm;
1216 /** @type {?} */
1217 Animation.prototype._rdFn;
1218 /** @type {?} */
1219 Animation.prototype._wrFn;
1220 /** @type {?} */
1221 Animation.prototype._fFn;
1222 /** @type {?} */
1223 Animation.prototype._fOneFn;
1224 /** @type {?} */
1225 Animation.prototype._rv;
1226 /** @type {?} */
1227 Animation.prototype._unrgTrns;
1228 /** @type {?} */
1229 Animation.prototype._tm;
1230 /** @type {?} */
1231 Animation.prototype._hasDur;
1232 /** @type {?} */
1233 Animation.prototype._isAsync;
1234 /** @type {?} */
1235 Animation.prototype._twn;
1236 /** @type {?} */
1237 Animation.prototype.plt;
1238 /** @type {?} */
1239 Animation.prototype.parent;
1240 /** @type {?} */
1241 Animation.prototype.opts;
1242 /** @type {?} */
1243 Animation.prototype.hasChildren;
1244 /** @type {?} */
1245 Animation.prototype.isPlaying;
1246 /** @type {?} */
1247 Animation.prototype.hasCompleted;
1248}
1249var /** @type {?} */ ANIMATION_TRANSFORMS = {
1250 'translateX': 1,
1251 'translateY': 1,
1252 'translateZ': 1,
1253 'scale': 1,
1254 'scaleX': 1,
1255 'scaleY': 1,
1256 'scaleZ': 1,
1257 'rotate': 1,
1258 'rotateX': 1,
1259 'rotateY': 1,
1260 'rotateZ': 1,
1261 'skewX': 1,
1262 'skewY': 1,
1263 'perspective': 1
1264};
1265var /** @type {?} */ ANIMATION_CSS_VALUE_REGEX = /(^-?\d*\.?\d*)(.*)/;
1266var /** @type {?} */ ANIMATION_DURATION_MIN = 32;
1267var /** @type {?} */ ANIMATION_TRANSITION_END_FALLBACK_PADDING_MS = 400;
1268//# sourceMappingURL=animation.js.map
\No newline at end of file