Files
controller-v2/client/src/lib/useStrokeDrawAnimation.ts
T

53 lines
1.4 KiB
TypeScript

import { useEffect } from "react";
/**
* Reusable left-to-right SVG stroke draw animation.
* Pass `enabled=false` to disable and clear dash styles (e.g. while dragging).
*/
export function useStrokeDrawAnimation(
pathRef: React.RefObject<SVGPathElement | null>,
pathD: string,
options?: {
enabled?: boolean;
durationMs?: number;
easing?: string;
},
) {
const enabled = options?.enabled ?? true;
const durationMs = options?.durationMs ?? 1350;
const easing = options?.easing ?? "cubic-bezier(0.33, 1, 0.68, 1)";
useEffect(() => {
const path = pathRef.current;
if (!path || !pathD) return;
if (!enabled) {
path.style.strokeDasharray = "";
path.style.strokeDashoffset = "";
path.style.transition = "";
return;
}
const length = path.getTotalLength();
if (!Number.isFinite(length) || length <= 0) return;
path.style.strokeDasharray = `${length}`;
path.style.strokeDashoffset = `${length}`;
path.style.transition = "none";
let cancelled = false;
const id = requestAnimationFrame(() => {
requestAnimationFrame(() => {
if (cancelled) return;
path.style.transition = `stroke-dashoffset ${durationMs}ms ${easing}`;
path.style.strokeDashoffset = "0";
});
});
return () => {
cancelled = true;
cancelAnimationFrame(id);
};
}, [pathRef, pathD, enabled, durationMs, easing]);
}