[Perf] useHeavyAnimationCheck: Support multiple heavy animations
This commit is contained in:
parent
ec6a28baf6
commit
79fca8ea1b
@ -245,6 +245,7 @@ function Transition({
|
||||
|
||||
requestMutation(() => {
|
||||
if (activeKey !== currentKeyRef.current) {
|
||||
dispatchHeavyAnimationStop();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -472,6 +473,7 @@ function performSlideOptimized(
|
||||
|
||||
requestMutation(() => {
|
||||
if (activeKey !== currentKeyRef.current) {
|
||||
dispatchHeavyAnimationStop();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ const AUTO_END_TIMEOUT = 1000;
|
||||
const startCallbacks = createCallbackManager();
|
||||
const endCallbacks = createCallbackManager();
|
||||
|
||||
let timeout: number | undefined;
|
||||
let counter = 0;
|
||||
|
||||
const [getIsAnimating, setIsAnimating] = createSignal(false);
|
||||
|
||||
@ -79,29 +79,31 @@ export function isHeavyAnimating() {
|
||||
}
|
||||
|
||||
export function dispatchHeavyAnimationEvent(duration = AUTO_END_TIMEOUT) {
|
||||
if (!getIsAnimating()) {
|
||||
counter++;
|
||||
|
||||
if (counter === 1) {
|
||||
setIsAnimating(true);
|
||||
startCallbacks.runCallbacks();
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
}
|
||||
const timeout = window.setTimeout(onEnd, duration);
|
||||
|
||||
let hasEnded = false;
|
||||
|
||||
// Race condition may happen if another `dispatchHeavyAnimationEvent` is called before `onEnd`
|
||||
function onEnd() {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
if (hasEnded) return;
|
||||
hasEnded = true;
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
counter--;
|
||||
|
||||
if (counter === 0) {
|
||||
setIsAnimating(false);
|
||||
endCallbacks.runCallbacks();
|
||||
}
|
||||
|
||||
setIsAnimating(false);
|
||||
endCallbacks.runCallbacks();
|
||||
}
|
||||
|
||||
timeout = window.setTimeout(onEnd, duration);
|
||||
|
||||
return onEnd;
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ type Params = Parameters<typeof createMutateFunction>;
|
||||
|
||||
let isAnimating = false;
|
||||
let currentArgs: Parameters<typeof createMutateFunction> | undefined;
|
||||
let onHeavyAnimationStop: NoneToVoidFunction | undefined;
|
||||
|
||||
export default function animateScroll(...args: Params | [...Params, boolean]) {
|
||||
currentArgs = args.slice(0, 8) as Params;
|
||||
@ -117,15 +118,18 @@ function createMutateFunction(
|
||||
return;
|
||||
}
|
||||
|
||||
isAnimating = true;
|
||||
|
||||
const transition = absPath <= FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE ? shortTransition : longTransition;
|
||||
const duration = forceDuration || (
|
||||
FAST_SMOOTH_MIN_DURATION
|
||||
+ (absPath / FAST_SMOOTH_MAX_DISTANCE) * (FAST_SMOOTH_MAX_DURATION - FAST_SMOOTH_MIN_DURATION)
|
||||
);
|
||||
const startAt = Date.now();
|
||||
const onHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
|
||||
isAnimating = true;
|
||||
|
||||
const prevOnHeavyAnimationStop = onHeavyAnimationStop;
|
||||
onHeavyAnimationStop = dispatchHeavyAnimationEvent();
|
||||
prevOnHeavyAnimationStop?.();
|
||||
|
||||
animateSingle(() => {
|
||||
const t = Math.min((Date.now() - startAt) / duration, 1);
|
||||
@ -138,7 +142,9 @@ function createMutateFunction(
|
||||
|
||||
if (!isAnimating) {
|
||||
currentArgs = undefined;
|
||||
onHeavyAnimationStop();
|
||||
|
||||
onHeavyAnimationStop!();
|
||||
onHeavyAnimationStop = undefined;
|
||||
}
|
||||
|
||||
return isAnimating;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user