{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "hyper-text", "type": "registry:ui", "title": "Hyper Text", "description": "A text effect that scrambles and cycles characters before revealing the final text, inspired by cyberpunk aesthetics.", "dependencies": [], "devDependencies": [], "registryDependencies": [], "files": [ { "path": "components/ui/hyper-text.tsx", "type": "registry:ui", "content": "\"use client\";\n\nimport { cn } from \"@workspace/ui/lib/utils\";\nimport { useEffect, useRef, useState } from \"react\";\n\ninterface HyperTextProps {\n className?: string;\n duration?: number;\n text: string;\n animateOnLoad?: boolean;\n}\n\nconst alphabets = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\nexport const HyperText = ({\n className,\n duration = 800,\n text,\n animateOnLoad = true,\n}: HyperTextProps) => {\n const [displayText, setDisplayText] = useState(text.split(\"\"));\n const [trigger, setTrigger] = useState(false);\n const iterations = useRef(0);\n const isFirstRender = useRef(true);\n\n const triggerAnimation = () => {\n iterations.current = 0;\n setTrigger(true);\n };\n\n useEffect(() => {\n const interval = setInterval(() => {\n if (!animateOnLoad && isFirstRender.current) {\n clearInterval(interval);\n isFirstRender.current = false;\n return;\n }\n if (iterations.current < text.length) {\n setDisplayText((t) =>\n t.map((l, i) =>\n l === \" \"\n ? l\n : i <= iterations.current\n ? text[i] ?? \"\"\n : alphabets[Math.floor(Math.random() * alphabets.length)]\n )\n );\n iterations.current = iterations.current + 0.1;\n } else {\n setTrigger(false);\n clearInterval(interval);\n }\n }, duration / (text.length * 10));\n // Clean up interval on unmount\n return () => clearInterval(interval);\n }, [text, duration, trigger, animateOnLoad]);\n\n return (\n \n {displayText.map((letter, i) => (\n \n {letter}\n \n ))}\n \n );\n};\n" } ], "tailwind": {}, "cssVars": {}, "meta": {} }