perf(animation): reduce flickering when updating css animation on lower end devices (#19138)

* fix flickering on lower end devices

* fix flickering, reduce timeout padding

* Add raf for clean up

* bug fix

* ensure animations are cleaned up

* Revert "ensure animations are cleaned up"

Thie reverts commit cf363f00be5567ba346d68659211087c8848d0d4.

* fix dependnecy

* Revert "ensure animations are cleaned up"
merge
This reverts commit cf363f00be5567ba346d68659211087c8848d0d4.
This commit is contained in:
Liam DeBeasi
2019-08-20 19:03:17 -04:00
committed by GitHub
parent 67ed89ded8
commit 45a59d13cc
2 changed files with 48 additions and 37 deletions

View File

@ -415,7 +415,7 @@ export class Menu implements ComponentInterface, MenuI {
let realDur = 0; let realDur = 0;
if (missingDistance > 5) { if (missingDistance > 5) {
const dur = missingDistance / Math.abs(velocity); const dur = missingDistance / Math.abs(velocity);
realDur = Math.min(dur, 300); realDur = Math.max(dur, 300);
} }
this.lastOnEnd = detail.timeStamp; this.lastOnEnd = detail.timeStamp;

View File

@ -43,7 +43,7 @@ export const createAnimation = () => {
const _afterAddWriteFunctions: any[] = []; const _afterAddWriteFunctions: any[] = [];
const webAnimations: any[] = []; const webAnimations: any[] = [];
const supportsWebAnimations = (typeof (window as any).Animation === 'function'); const supportsWebAnimations = (typeof (window as any).Animation === 'function');
const ANIMATION_END_FALLBACK_PADDING_MS = 400; const ANIMATION_END_FALLBACK_PADDING_MS = 100;
/** /**
* Returns the raw Web Animations object * Returns the raw Web Animations object
@ -713,6 +713,7 @@ export const createAnimation = () => {
const updateCSSAnimation = (toggleAnimationName = true) => { const updateCSSAnimation = (toggleAnimationName = true) => {
elements.forEach(element => { elements.forEach(element => {
requestAnimationFrame(() => {
setStyleProperty(element, 'animation-name', keyframeName || null); setStyleProperty(element, 'animation-name', keyframeName || null);
setStyleProperty(element, 'animation-duration', (getDuration() !== undefined) ? `${getDuration()}ms` : null); setStyleProperty(element, 'animation-duration', (getDuration() !== undefined) ? `${getDuration()}ms` : null);
setStyleProperty(element, 'animation-timing-function', getEasing() || null); setStyleProperty(element, 'animation-timing-function', getEasing() || null);
@ -735,6 +736,7 @@ export const createAnimation = () => {
setStyleProperty(element, 'animation-name', keyframeName || null); setStyleProperty(element, 'animation-name', keyframeName || null);
}); });
}); });
});
}; };
/** /**
@ -905,7 +907,9 @@ export const createAnimation = () => {
elements.forEach(element => { elements.forEach(element => {
if (_keyframes.length > 0) { if (_keyframes.length > 0) {
requestAnimationFrame(() => {
setStyleProperty(element, 'animation-play-state', 'running'); setStyleProperty(element, 'animation-play-state', 'running');
});
} }
}); });
@ -927,20 +931,34 @@ export const createAnimation = () => {
animationEnd(elements[0], () => { animationEnd(elements[0], () => {
clearCSSAnimationsTimeout(); clearCSSAnimationsTimeout();
/**
* Ensure that clean up
* is always done a frame
* before the onFinish handlers
* are fired. Otherwise, there
* may be flickering if a new
* animation is started on the same
* element too quickly
*
* TODO: Is there a cleaner way to do this?
*/
requestAnimationFrame(() => {
clearCSSAnimationPlayState(); clearCSSAnimationPlayState();
requestAnimationFrame(() => {
animationFinish(); animationFinish();
}); });
});
});
} }
}; };
const clearCSSAnimationPlayState = () => { const clearCSSAnimationPlayState = () => {
elements.forEach(element => { elements.forEach(element => {
requestAnimationFrame(() => {
removeStyleProperty(element, 'animation-duration'); removeStyleProperty(element, 'animation-duration');
removeStyleProperty(element, 'animation-delay'); removeStyleProperty(element, 'animation-delay');
removeStyleProperty(element, 'animation-play-state'); removeStyleProperty(element, 'animation-play-state');
}); });
});
}; };
const playWebAnimations = () => { const playWebAnimations = () => {
@ -953,18 +971,11 @@ export const createAnimation = () => {
} }
}; };
const resetCSSAnimations = () => {
elements.forEach(element => {
const newKeyframeName = (keyframeName !== undefined) ? `${keyframeName}-alt` : null;
setStyleProperty(element, 'animation-name', newKeyframeName);
});
};
const resetAnimation = () => { const resetAnimation = () => {
if (supportsWebAnimations) { if (supportsWebAnimations) {
setAnimationStep(0); setAnimationStep(0);
} else { } else {
resetCSSAnimations(); updateCSSAnimation();
} }
}; };
@ -973,7 +984,7 @@ export const createAnimation = () => {
*/ */
const play = () => { const play = () => {
if (!initialized) { if (!initialized) {
initializeAnimation(false); initializeAnimation();
} }
if (finished) { if (finished) {