From 7bd44128895b9fa4992142c0cc30cf75092cb794 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Thu, 31 Oct 2019 12:50:54 -0400 Subject: [PATCH] fix(animation): track correctly when updating CSS Animation (#19813) * fix bug * update menu * fix --- core/src/components/menu/menu.tsx | 17 +++++++---- .../utils/animation/animation-interface.ts | 2 +- core/src/utils/animation/animation.ts | 30 ++++++++++--------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index 42cb233717..b632a935da 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -337,7 +337,12 @@ AFTER: const isReversed = !shouldOpen; const ani = (this.animation as Animation)! .direction((isReversed) ? 'reverse' : 'normal') - .easing((isReversed) ? this.easingReverse : this.easing); + .easing((isReversed) ? this.easingReverse : this.easing) + .onFinish(() => { + if (ani.getDirection() === 'reverse') { + ani.direction('normal'); + } + }); if (animated) { await ani.play(); @@ -384,9 +389,7 @@ AFTER: } // the cloned animation should not use an easing curve during seek - (this.animation as Animation) - .direction((this._isOpen) ? 'reverse' : 'normal') - .progressStart(true); + (this.animation as Animation).progressStart(true, (this._isOpen) ? 1 : 0); } private onMove(detail: GestureDetail) { @@ -398,7 +401,7 @@ AFTER: const delta = computeDelta(detail.deltaX, this._isOpen, this.isEndSide); const stepValue = delta / this.width; - this.animation.progressStep(stepValue); + this.animation.progressStep((this._isOpen) ? 1 - stepValue : stepValue); } private onEnd(detail: GestureDetail) { @@ -451,12 +454,14 @@ AFTER: */ newStepValue += getTimeGivenProgression([0, 0], [0.4, 0], [0.6, 1], [1, 1], clamp(0, adjustedStepValue, 1))[0]; + const playTo = (this._isOpen) ? !shouldComplete : shouldComplete; + this.animation .easing('cubic-bezier(0.4, 0.0, 0.6, 1)') .onFinish( () => this.afterAnimation(shouldOpen), { oneTimeCallback: true }) - .progressEnd(shouldComplete ? 1 : 0, newStepValue, 300); + .progressEnd((playTo) ? 1 : 0, (this._isOpen) ? 1 - newStepValue : newStepValue, 300); } private beforeAnimation(shouldOpen: boolean) { diff --git a/core/src/utils/animation/animation-interface.ts b/core/src/utils/animation/animation-interface.ts index 3ed04870b1..f856d2f261 100644 --- a/core/src/utils/animation/animation-interface.ts +++ b/core/src/utils/animation/animation-interface.ts @@ -29,7 +29,7 @@ export interface Animation { */ destroy(): void; - progressStart(forceLinearEasing: boolean): void; + progressStart(forceLinearEasing: boolean, step?: number): void; progressStep(step: number): void; progressEnd(playTo: 0 | 1 | undefined, step: number, dur?: number): void; diff --git a/core/src/utils/animation/animation.ts b/core/src/utils/animation/animation.ts index e065119a23..baf677f838 100644 --- a/core/src/utils/animation/animation.ts +++ b/core/src/utils/animation/animation.ts @@ -19,7 +19,7 @@ interface AnimationInternal extends Animation { /** * Updates any existing animations. */ - update(deep: boolean): Animation; + update(deep: boolean, toggleAnimationName: boolean, step?: number): Animation; animationFinish(): void; } @@ -611,8 +611,7 @@ export const createAnimation = (animationId?: string): Animation => { }); } else { - const animationDelay = getDelay() || 0; - const animationDuration = `-${animationDelay + (getDuration()! * step)}ms`; + const animationDuration = `-${getDuration()! * step}ms`; elements.forEach(element => { if (_keyframes.length > 0) { @@ -623,7 +622,7 @@ export const createAnimation = (animationId?: string): Animation => { } }; - const updateWebAnimation = () => { + const updateWebAnimation = (step?: number) => { webAnimations.forEach(animation => { animation.effect.updateTiming({ delay: getDelay(), @@ -634,15 +633,19 @@ export const createAnimation = (animationId?: string): Animation => { direction: getDirection() }); }); + + if (step !== undefined) { + setAnimationStep(step); + } }; - const updateCSSAnimation = (toggleAnimationName = true) => { + const updateCSSAnimation = (toggleAnimationName = true, step?: number) => { raf(() => { elements.forEach(element => { setStyleProperty(element, 'animation-name', keyframeName || null); setStyleProperty(element, 'animation-duration', `${getDuration()}ms`); setStyleProperty(element, 'animation-timing-function', getEasing()); - setStyleProperty(element, 'animation-delay', `${getDelay()}ms`); + setStyleProperty(element, 'animation-delay', (step !== undefined) ? `-${step! * getDuration()}ms` : `${getDelay()}ms`); setStyleProperty(element, 'animation-fill-mode', getFill() || null); setStyleProperty(element, 'animation-direction', getDirection() || null); @@ -663,25 +666,25 @@ export const createAnimation = (animationId?: string): Animation => { }); }; - const update = (deep = false, toggleAnimationName = true) => { + const update = (deep = false, toggleAnimationName = true, step?: number) => { if (deep) { childAnimations.forEach(animation => { - animation.update(deep); + animation.update(deep, toggleAnimationName, step); }); } if (supportsWebAnimations) { - updateWebAnimation(); + updateWebAnimation(step); } else { - updateCSSAnimation(toggleAnimationName); + updateCSSAnimation(toggleAnimationName, step); } return ani; }; - const progressStart = (forceLinearEasing = false) => { + const progressStart = (forceLinearEasing = false, step?: number) => { childAnimations.forEach(animation => { - animation.progressStart(forceLinearEasing); + animation.progressStart(forceLinearEasing, step); }); pauseAnimation(); @@ -690,8 +693,7 @@ export const createAnimation = (animationId?: string): Animation => { if (!initialized) { initializeAnimation(); } else { - update(); - setAnimationStep(0); + update(false, true, step); } return ani;