'use client'; import Image from "next/image"; import { useEffect, useRef, useState } from "react"; interface Props { src?: string; fillSrc?: string; reverseOrder?: boolean; } export function SignatureDrawing({ src = "/sign.svg", fillSrc, reverseOrder = true, }: Props) { const [paths, setPaths] = useState([]); const svgRef = useRef(null); const [showFill, setShowFill] = useState(false); const timeoutRef = useRef(null); useEffect(() => { let mounted = true; fetch(src) .then((res) => res.text()) .then((text) => { if (!mounted) return; const parser = new DOMParser(); const doc = parser.parseFromString(text, "image/svg+xml"); const extracted = Array.from(doc.querySelectorAll("path")) .map((node) => node.getAttribute("d") ?? "") .filter(Boolean); const d = reverseOrder ? extracted.reverse() : extracted; setShowFill(false); setPaths(d); }) .catch(() => setShowFill(true)); return () => { mounted = false; }; }, [src, reverseOrder]); useEffect(() => { if (!svgRef.current) return; const nodes = svgRef.current.querySelectorAll("path"); let cumulative = 0; nodes.forEach((node) => { const length = node.getTotalLength(); const duration = Math.max(0.08, length / 800); node.style.setProperty("--path-length", `${length}`); node.style.strokeDasharray = `${length}`; node.style.strokeDashoffset = `${length}`; node.style.animationDuration = `${duration}s`; node.style.animationDelay = `${cumulative}s`; cumulative += duration; }); if (timeoutRef.current) clearTimeout(timeoutRef.current); timeoutRef.current = setTimeout(() => setShowFill(true), cumulative * 1000 + 250); return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current); }; }, [paths]); return (
{paths.map((d, idx) => ( ))} {showFill && ( Handwritten signature )}
); }