Files

54 lines
1.5 KiB
TypeScript

"use client";
import { motion } from "motion/react";
export function FloatingPaths({ position }: { position: number }) {
const paths = Array.from({ length: 36 }, (_, i) => ({
id: i,
d: `M-${380 - i * 5 * position} -${189 + i * 6}C-${
380 - i * 5 * position
} -${189 + i * 6} -${312 - i * 5 * position} ${216 - i * 6} ${
152 - i * 5 * position
} ${343 - i * 6}C${616 - i * 5 * position} ${470 - i * 6} ${
684 - i * 5 * position
} ${875 - i * 6} ${684 - i * 5 * position} ${875 - i * 6}`,
color: `rgba(15,23,42,${0.1 + i * 0.03})`,
width: 0.5 + i * 0.03,
}));
return (
<div className="pointer-events-none absolute inset-0">
<svg
className="h-full w-full text-primary"
fill="none"
viewBox="0 0 696 316"
>
<title>Background Paths</title>
{paths.map((path) => (
<motion.path
animate={{
pathLength: 1,
opacity: [0.3, 0.6, 0.3],
}}
d={path.d}
initial={{ pathLength: 0.3, opacity: 0.6 }}
key={path.id}
stroke="currentColor"
strokeOpacity={0.1 + path.id * 0.03}
strokeWidth={path.width}
transition={{
// Animating pathOffset forces a stroke-dasharray recompute on
// every frame for all 36 paths — opacity alone is far cheaper.
pathLength: { duration: 2, ease: "easeOut" },
opacity: {
duration: 20 + (path.id % 10),
repeat: Number.POSITIVE_INFINITY,
ease: "linear",
},
}}
/>
))}
</svg>
</div>
);
}