mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 03:32:21 +08:00
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:
@ -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;
|
||||||
|
@ -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,26 +713,28 @@ export const createAnimation = () => {
|
|||||||
|
|
||||||
const updateCSSAnimation = (toggleAnimationName = true) => {
|
const updateCSSAnimation = (toggleAnimationName = true) => {
|
||||||
elements.forEach(element => {
|
elements.forEach(element => {
|
||||||
setStyleProperty(element, 'animation-name', keyframeName || null);
|
|
||||||
setStyleProperty(element, 'animation-duration', (getDuration() !== undefined) ? `${getDuration()}ms` : null);
|
|
||||||
setStyleProperty(element, 'animation-timing-function', getEasing() || null);
|
|
||||||
setStyleProperty(element, 'animation-delay', (getDelay() !== undefined) ? `${getDelay()}ms` : null);
|
|
||||||
setStyleProperty(element, 'animation-fill-mode', getFill() || null);
|
|
||||||
setStyleProperty(element, 'animation-direction', getDirection() || null);
|
|
||||||
|
|
||||||
const iterationsCount =
|
|
||||||
(getIterations() !== undefined) ?
|
|
||||||
(getIterations() === Infinity) ? 'infinite' : getIterations()!.toString()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
|
|
||||||
|
|
||||||
if (toggleAnimationName) {
|
|
||||||
setStyleProperty(element, 'animation-name', `${keyframeName}-alt`);
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
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-timing-function', getEasing() || null);
|
||||||
|
setStyleProperty(element, 'animation-delay', (getDelay() !== undefined) ? `${getDelay()}ms` : null);
|
||||||
|
setStyleProperty(element, 'animation-fill-mode', getFill() || null);
|
||||||
|
setStyleProperty(element, 'animation-direction', getDirection() || null);
|
||||||
|
|
||||||
|
const iterationsCount =
|
||||||
|
(getIterations() !== undefined) ?
|
||||||
|
(getIterations() === Infinity) ? 'infinite' : getIterations()!.toString()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
|
||||||
|
|
||||||
|
if (toggleAnimationName) {
|
||||||
|
setStyleProperty(element, 'animation-name', `${keyframeName}-alt`);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
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) {
|
||||||
setStyleProperty(element, 'animation-play-state', 'running');
|
requestAnimationFrame(() => {
|
||||||
|
setStyleProperty(element, 'animation-play-state', 'running');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -927,19 +931,33 @@ export const createAnimation = () => {
|
|||||||
|
|
||||||
animationEnd(elements[0], () => {
|
animationEnd(elements[0], () => {
|
||||||
clearCSSAnimationsTimeout();
|
clearCSSAnimationsTimeout();
|
||||||
clearCSSAnimationPlayState();
|
|
||||||
animationFinish();
|
/**
|
||||||
|
* 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 = () => {
|
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');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -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) {
|
||||||
|
Reference in New Issue
Block a user