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