{ "name": "background-paths", "type": "registry:component", "dependencies": [ "motion" ], "files": [ { "type": "registry:component", "content": "\"use client\";\n\n/**\n * @author: @dorianbaffier\n * @description: Background Paths\n * @version: 1.0.0\n * @date: 2025-06-26\n * @license: MIT\n * @website: https://kokonutui.com\n * @github: https://github.com/kokonut-labs/kokonutui\n */\n\nimport { motion } from \"motion/react\";\nimport { memo, useMemo } from \"react\";\n\ninterface Point {\n x: number;\n y: number;\n}\n\ninterface PathData {\n id: string;\n d: string;\n opacity: number;\n width: number;\n duration: number;\n delay: number;\n}\n\n// Path generation function\nfunction generateAestheticPath(\n index: number,\n position: number,\n type: \"primary\" | \"secondary\" | \"accent\"\n): string {\n const baseAmplitude =\n type === \"primary\" ? 150 : type === \"secondary\" ? 100 : 60;\n const phase = index * 0.2;\n const points: Point[] = [];\n const segments = type === \"primary\" ? 10 : type === \"secondary\" ? 8 : 6;\n\n const startX = 2400;\n const startY = 800;\n const endX = -2400;\n const endY = -800 + index * 25;\n\n for (let i = 0; i <= segments; i++) {\n const progress = i / segments;\n const eased = 1 - (1 - progress) ** 2;\n\n const baseX = startX + (endX - startX) * eased;\n const baseY = startY + (endY - startY) * eased;\n\n const amplitudeFactor = 1 - eased * 0.3;\n const wave1 =\n Math.sin(progress * Math.PI * 3 + phase) *\n (baseAmplitude * 0.7 * amplitudeFactor);\n const wave2 =\n Math.cos(progress * Math.PI * 4 + phase) *\n (baseAmplitude * 0.3 * amplitudeFactor);\n const wave3 =\n Math.sin(progress * Math.PI * 2 + phase) *\n (baseAmplitude * 0.2 * amplitudeFactor);\n\n points.push({\n x: baseX * position,\n y: baseY + wave1 + wave2 + wave3,\n });\n }\n\n const pathCommands = points.map((point: Point, i: number) => {\n if (i === 0) return `M ${point.x} ${point.y}`;\n const prevPoint = points[i - 1];\n const tension = 0.4;\n const cp1x = prevPoint.x + (point.x - prevPoint.x) * tension;\n const cp1y = prevPoint.y;\n const cp2x = prevPoint.x + (point.x - prevPoint.x) * (1 - tension);\n const cp2y = point.y;\n return `C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${point.x} ${point.y}`;\n });\n\n return pathCommands.join(\" \");\n}\n\nconst generateUniqueId = (prefix: string): string =>\n `${prefix}-${Math.random().toString(36).substr(2, 9)}`;\n\n// Memoized FloatingPaths component\nconst FloatingPaths = memo(function FloatingPaths({\n position,\n}: {\n position: number;\n}) {\n // Increased number of paths while maintaining optimization\n const primaryPaths: PathData[] = useMemo(\n () =>\n Array.from({ length: 12 }, (_, i) => ({\n id: generateUniqueId(\"primary\"),\n d: generateAestheticPath(i, position, \"primary\"),\n opacity: 0.15 + i * 0.02,\n width: 4 + i * 0.3,\n duration: 25,\n delay: 0,\n })),\n [position]\n );\n\n const secondaryPaths: PathData[] = useMemo(\n () =>\n Array.from({ length: 15 }, (_, i) => ({\n id: generateUniqueId(\"secondary\"),\n d: generateAestheticPath(i, position, \"secondary\"),\n opacity: 0.12 + i * 0.015,\n width: 3 + i * 0.25,\n duration: 20,\n delay: 0,\n })),\n [position]\n );\n\n const accentPaths: PathData[] = useMemo(\n () =>\n Array.from({ length: 10 }, (_, i) => ({\n id: generateUniqueId(\"accent\"),\n d: generateAestheticPath(i, position, \"accent\"),\n opacity: 0.08 + i * 0.12,\n width: 2 + i * 0.2,\n duration: 15,\n delay: 0,\n })),\n [position]\n );\n\n // Shared animation configuration\n const sharedAnimationProps = {\n opacity: 1,\n scale: 1,\n transition: {\n opacity: { duration: 1 },\n scale: { duration: 1 },\n },\n };\n\n return (\n
\n \n Background Paths\n \n \n \n \n \n \n \n\n \n {primaryPaths.map((path) => (\n \n ))}\n \n\n \n {secondaryPaths.map((path) => (\n \n ))}\n \n\n \n {accentPaths.map((path) => (\n \n ))}\n \n \n
\n );\n});\n\n// Memoized AnimatedTitle component\nconst AnimatedTitle = memo(function AnimatedTitle({\n title,\n}: {\n title: string;\n}) {\n return (\n \n {title}\n \n );\n});\n\nexport default memo(function BackgroundPaths({\n title = \"Background Paths\",\n}: {\n title?: string;\n}) {\n return (\n
\n
\n \n
\n\n
\n \n \n \n
\n
\n );\n});\n", "path": "/components/kokonutui/background-paths.tsx", "target": "components/kokonutui/background-paths.tsx" } ] }