Velocity UI
Loading…
Menu

Hyper Text

A cyberpunk-inspired text effect that scrambles characters randomly before resolving to the final text on hover or load.

Installation

Add this component to your project using the CLI:

terminal
npx vui-registry-cli-v1 add hyper-text

Source Code

hyper-text.tsx
'use client';

import { useEffect, useRef, useState } from 'react';
import { cn } from '@/lib/utils';

export default function HyperText({
  text = 'Velocity UI',
  className,
  duration = 800,
}: {
  text?: string;
  className?: string;
  duration?: number;
}) {
  const [displayText, setDisplayText] = useState(text.split(''));
  const [isAnimating, setIsAnimating] = useState(false);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+';

  const startAnimation = () => {
    setIsAnimating(true);
    let iteration = 0;
    
    if (intervalRef.current) clearInterval(intervalRef.current);
    
    intervalRef.current = setInterval(() => {
      setDisplayText((currentText) =>
        text.split('').map((letter, index) => {
          if (letter === ' ') return letter;
          if (index < iteration) {
            return text[index];
          }
          return alphabets[Math.floor(Math.random() * alphabets.length)];
        })
      );

      if (iteration >= text.length) {
        if (intervalRef.current) clearInterval(intervalRef.current);
        setIsAnimating(false);
      }
      
      iteration += 1 / 3; 
    }, 30); 
  };

  // Trigger on mount for demo
  useEffect(() => {
    startAnimation();
  }, []);

  return (
    <div
      className={cn("flex overflow-hidden py-2 cursor-pointer select-none", className)}
      onMouseEnter={startAnimation}
    >
        <span className="sr-only">{text}</span>
        {displayText.map((char, i) => (
            <span key={i} className="font-mono inline-block w-[0.6em] text-center">
                {char}
            </span>
        ))}
    </div>
  );
}

Dependencies

  • framer-motion: latest