mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
- Add varsIgnorePattern to no-unused-vars for destructuring patterns - Fix all react-hooks/exhaustive-deps by adding missing dependencies - Refactor useAnimatedNumber to use ref instead of stale state closure - Wrap handleLinkResult in useCallback for stable deps - Extract OAuth utilities from OAuthCallback.tsx to utils/oauth.ts - Extract background config utilities to utils/backgroundConfig.ts - Remove unused catch parameter in GiftSubscription
34 lines
1.0 KiB
TypeScript
34 lines
1.0 KiB
TypeScript
import { useEffect, useRef, useState } from 'react';
|
|
|
|
/**
|
|
* Animates a number from its current value to a new target.
|
|
* Uses easeOutExpo easing matching the prototype.
|
|
*/
|
|
export function useAnimatedNumber(target: number, duration = 1200): number {
|
|
const [value, setValue] = useState(0);
|
|
const currentRef = useRef(0);
|
|
const rafRef = useRef<number>(0);
|
|
|
|
useEffect(() => {
|
|
const start = currentRef.current;
|
|
const startTime = performance.now();
|
|
|
|
const animate = (now: number) => {
|
|
const elapsed = now - startTime;
|
|
const progress = Math.min(elapsed / duration, 1);
|
|
const ease = progress === 1 ? 1 : 1 - Math.pow(2, -10 * progress);
|
|
const current = start + (target - start) * ease;
|
|
currentRef.current = current;
|
|
setValue(current);
|
|
if (progress < 1) {
|
|
rafRef.current = requestAnimationFrame(animate);
|
|
}
|
|
};
|
|
|
|
rafRef.current = requestAnimationFrame(animate);
|
|
return () => cancelAnimationFrame(rafRef.current);
|
|
}, [target, duration]);
|
|
|
|
return value;
|
|
}
|