{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "matrix-demo", "registryDependencies": [ "https://ui.elevenlabs.io/r/matrix.json" ], "files": [ { "path": "examples/matrix-demo.tsx", "content": "\"use client\"\n\nimport { useEffect, useState } from \"react\"\n\nimport {\n Matrix,\n pulse,\n snake,\n wave,\n type Frame,\n} from \"@/components/ui/matrix\"\n\nconst Example = () => {\n const [mode, setMode] = useState<\n \"individual\" | \"focus\" | \"expand\" | \"unified\" | \"collapse\" | \"burst\"\n >(\"individual\")\n const [unifiedFrame, setUnifiedFrame] = useState(0)\n const [expandProgress, setExpandProgress] = useState(0)\n const [collapseProgress, setCollapseProgress] = useState(0)\n\n useEffect(() => {\n let timeout: NodeJS.Timeout\n\n if (mode === \"individual\") {\n timeout = setTimeout(() => setMode(\"focus\"), 4000)\n } else if (mode === \"focus\") {\n timeout = setTimeout(() => setMode(\"expand\"), 2000)\n } else if (mode === \"expand\") {\n timeout = setTimeout(() => setMode(\"unified\"), 2500)\n } else if (mode === \"unified\") {\n timeout = setTimeout(() => setMode(\"collapse\"), 4000)\n } else if (mode === \"collapse\") {\n timeout = setTimeout(() => setMode(\"burst\"), 2500)\n } else if (mode === \"burst\") {\n timeout = setTimeout(() => setMode(\"individual\"), 800)\n }\n\n return () => clearTimeout(timeout)\n }, [mode])\n\n useEffect(() => {\n if (mode !== \"unified\") return\n\n let frame = 0\n const animate = setInterval(() => {\n frame += 1\n setUnifiedFrame(frame)\n }, 50)\n\n return () => clearInterval(animate)\n }, [mode])\n\n useEffect(() => {\n if (mode !== \"expand\") {\n setExpandProgress(0)\n return\n }\n\n let start = 0\n const duration = 2500\n let animationFrame: number\n\n const animate = (timestamp: number) => {\n if (start === 0) start = timestamp\n const elapsed = timestamp - start\n const progress = Math.min(elapsed / duration, 1)\n\n setExpandProgress(progress)\n\n if (progress < 1) {\n animationFrame = requestAnimationFrame(animate)\n }\n }\n\n animationFrame = requestAnimationFrame(animate)\n return () => cancelAnimationFrame(animationFrame)\n }, [mode])\n\n useEffect(() => {\n if (mode !== \"collapse\") {\n setCollapseProgress(0)\n return\n }\n\n let start = 0\n const duration = 2500\n let animationFrame: number\n\n const animate = (timestamp: number) => {\n if (start === 0) start = timestamp\n const elapsed = timestamp - start\n const progress = Math.min(elapsed / duration, 1)\n\n setCollapseProgress(progress)\n\n if (progress < 1) {\n animationFrame = requestAnimationFrame(animate)\n }\n }\n\n animationFrame = requestAnimationFrame(animate)\n return () => cancelAnimationFrame(animationFrame)\n }, [mode])\n\n const configurations = [\n { animation: pulse, fps: 16 },\n { animation: wave, fps: 20 },\n { animation: spinner, fps: 10 },\n { animation: snake, fps: 15 },\n { animation: elevenLogo, fps: 12 },\n { animation: sandTimer, fps: 12 },\n { animation: corners, fps: 10 },\n { animation: sweep, fps: 14 },\n { animation: expand, fps: 12 },\n ]\n\n const unifiedPatterns =\n mode === \"unified\" ? createUnifiedPattern(unifiedFrame) : []\n\n const expandedPatterns =\n mode === \"expand\" ? createExpandedLogo(expandProgress) : []\n const collapsePatterns =\n mode === \"collapse\" ? createCollapseEffect(collapseProgress) : []\n\n const getPatternForMatrix = (index: number) => {\n if (mode === \"individual\") {\n return undefined\n } else if (mode === \"focus\") {\n if (index === 4) {\n const frame: Frame = Array(7)\n .fill(0)\n .map(() => Array(7).fill(0))\n for (let r = 1; r <= 5; r++) {\n frame[r][2] = 1\n frame[r][4] = 1\n }\n return frame\n }\n return Array(7)\n .fill(0)\n .map(() => Array(7).fill(0))\n } else if (mode === \"expand\") {\n return expandedPatterns[index]\n } else if (mode === \"unified\") {\n return unifiedPatterns[index]\n } else if (mode === \"collapse\") {\n return collapsePatterns[index]\n } else if (mode === \"burst\") {\n return undefined\n }\n }\n\n const getFramesForMatrix = (index: number) => {\n if (mode === \"individual\") {\n return configurations[index].animation\n } else if (mode === \"burst\") {\n return burst\n }\n return undefined\n }\n\n const getFps = (index: number) => {\n if (mode === \"burst\") return 30\n return configurations[index].fps\n }\n\n return (\n