Hyper Text
A zero-dependency, ultra-lightweight text component that creates a hacker-style scrambling text effect on hover or load. Perfect for viral marketing pages and high-performance React applications.
Preview
BARE UI
Installation
Copy and paste the following code into your project.
tsx
"use client";
import React, { useState, useEffect, useRef } from "react";
export interface HyperTextProps extends React.HTMLAttributes<HTMLDivElement> {
text: string;
duration?: number;
className?: string;
animateOnLoad?: boolean;
}
const alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
const getRandomInt = (max: number) => Math.floor(Math.random() * max);
export const HyperText = ({
text,
duration = 800,
className = "",
animateOnLoad = true,
...props
}: HyperTextProps) => {
const [displayText, setDisplayText] = useState<string[]>(text.split(""));
const [trigger, setTrigger] = useState(animateOnLoad);
const interations = useRef(0);
const isFirstRender = useRef(true);
const triggerAnimation = () => {
interations.current = 0;
setTrigger(true);
};
useEffect(() => {
if (isFirstRender.current) {
isFirstRender.current = false;
if (!animateOnLoad) return;
}
const interval = setInterval(
() => {
if (!trigger) {
clearInterval(interval);
return;
}
if (interations.current < text.length) {
setDisplayText((t) =>
t.map((l, i) =>
l === " "
? l
: i <= interations.current
? (text[i] as string)
: (alphabets[getRandomInt(26)] as string),
),
);
interations.current = interations.current + 0.1;
} else {
setTrigger(false);
clearInterval(interval);
}
},
duration / (text.length * 10),
);
return () => clearInterval(interval);
}, [text, duration, trigger, animateOnLoad]);
return (
<div
className={`bare-hyper-text ${className}`}
onMouseEnter={triggerAnimation}
{...props}
>
{displayText.map((letter, i) => (
<span key={i} className="bare-hyper-text-letter">
{letter}
</span>
))}
</div>
);
};