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;
if (missingDistance > 5) {
const dur = missingDistance / Math.abs(velocity);
realDur = Math.min(dur, 300);
realDur = Math.max(dur, 300);
}
this.lastOnEnd = detail.timeStamp;

View File

@ -43,7 +43,7 @@ export const createAnimation = () => {
const _afterAddWriteFunctions: any[] = [];
const webAnimations: any[] = [];
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
@ -713,6 +713,7 @@ export const createAnimation = () => {
const updateCSSAnimation = (toggleAnimationName = true) => {
elements.forEach(element => {
requestAnimationFrame(() => {
setStyleProperty(element, 'animation-name', keyframeName || null);
setStyleProperty(element, 'animation-duration', (getDuration() !== undefined) ? `${getDuration()}ms` : null);
setStyleProperty(element, 'animation-timing-function', getEasing() || null);
@ -735,6 +736,7 @@ export const createAnimation = () => {
setStyleProperty(element, 'animation-name', keyframeName || null);
});
});
});
};
/**
@ -905,7 +907,9 @@ export const createAnimation = () => {
elements.forEach(element => {
if (_keyframes.length > 0) {
requestAnimationFrame(() => {
setStyleProperty(element, 'animation-play-state', 'running');
});
}
});
@ -927,20 +931,34 @@ export const createAnimation = () => {
animationEnd(elements[0], () => {
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();
requestAnimationFrame(() => {
animationFinish();
});
});
});
}
};
const clearCSSAnimationPlayState = () => {
elements.forEach(element => {
requestAnimationFrame(() => {
removeStyleProperty(element, 'animation-duration');
removeStyleProperty(element, 'animation-delay');
removeStyleProperty(element, 'animation-play-state');
});
});
};
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 = () => {
if (supportsWebAnimations) {
setAnimationStep(0);
} else {
resetCSSAnimations();
updateCSSAnimation();
}
};
@ -973,7 +984,7 @@ export const createAnimation = () => {
*/
const play = () => {
if (!initialized) {
initializeAnimation(false);
initializeAnimation();
}
if (finished) {