added MoreSection component to profile page
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useRef, useCallback } from "react";
|
||||
|
||||
export function useStaggerReveal(count: number, baseDelay = 80) {
|
||||
const [visible, setVisible] = useState<Set<number>>(new Set());
|
||||
@@ -31,3 +31,63 @@ export function useMountTransition(delay = 50) {
|
||||
|
||||
return mounted;
|
||||
}
|
||||
|
||||
|
||||
export function useWiggle(durationMs = 1500, onComplete: () => void) {
|
||||
const [wiggling, setWiggling] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
|
||||
const startTime = useRef<number>(0);
|
||||
const rafId = useRef<number>(0);
|
||||
const completeTimer = useRef<ReturnType<typeof setTimeout>>(null);
|
||||
const completedRef = useRef(false);
|
||||
|
||||
const stop = useCallback(() => {
|
||||
setWiggling(false);
|
||||
setProgress(0);
|
||||
cancelAnimationFrame(rafId.current);
|
||||
if (completeTimer.current) clearTimeout(completeTimer.current);
|
||||
}, []);
|
||||
|
||||
const tick = useCallback(() => {
|
||||
const elapsed = Date.now() - startTime.current;
|
||||
const p = Math.min(1, elapsed / durationMs);
|
||||
setProgress(p);
|
||||
if (p < 1) {
|
||||
rafId.current = requestAnimationFrame(tick);
|
||||
}
|
||||
}, [durationMs]);
|
||||
|
||||
const start = useCallback(() => {
|
||||
completedRef.current = false;
|
||||
startTime.current = Date.now();
|
||||
setWiggling(true);
|
||||
setProgress(0);
|
||||
rafId.current = requestAnimationFrame(tick);
|
||||
|
||||
completeTimer.current = setTimeout(() => {
|
||||
completedRef.current = true;
|
||||
stop();
|
||||
onComplete();
|
||||
}, durationMs);
|
||||
}, [durationMs, onComplete, tick, stop]);
|
||||
|
||||
const release = useCallback(() => {
|
||||
if (!completedRef.current) stop();
|
||||
}, [stop]);
|
||||
|
||||
// cleanup on unmount
|
||||
useEffect(() => () => {
|
||||
cancelAnimationFrame(rafId.current);
|
||||
if (completeTimer.current) clearTimeout(completeTimer.current);
|
||||
}, []);
|
||||
|
||||
const handlers = {
|
||||
onPointerDown: start,
|
||||
onPointerEnter: start,
|
||||
onPointerUp: release,
|
||||
onPointerLeave: release,
|
||||
};
|
||||
|
||||
return { wiggling, progress, handlers };
|
||||
}
|
||||
Reference in New Issue
Block a user