Hyper Text
A hover-triggered text animation with random letter effects using Framer Motion.
A hover-triggered text animation with random letter effects using Framer Motion.
npm install framer-motion
"use client";import { useEffect, useRef, useState } from "react";import { AnimatePresence, motion, Variants } from "framer-motion";import { cn } from "@/lib/utils";interface HyperTextProps {text: string;duration?: number;framerProps?: Variants;className?: string;animateOnLoad?: boolean;}const alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");const getRandomInt = (max: number) => Math.floor(Math.random() * max);export function HyperText({text,duration = 800,framerProps = {initial: { opacity: 0, y: -10 },animate: { opacity: 1, y: 0 },exit: { opacity: 0, y: 3 },},className,animateOnLoad = true,}: HyperTextProps) {const [displayText, setDisplayText] = useState(text.split(""));const [trigger, setTrigger] = useState(false);const interations = useRef(0);const isFirstRender = useRef(true);const triggerAnimation = () => {interations.current = 0;setTrigger(true);};useEffect(() => {const interval = setInterval(() => {if (!animateOnLoad && isFirstRender.current) {clearInterval(interval);isFirstRender.current = false;return;}if (interations.current < text.length) {setDisplayText((t) =>t.map((l, i) =>l === " "? l: i <= interations.current? text[i]: alphabets[getRandomInt(26)],),);interations.current = interations.current + 0.1;} else {setTrigger(false);clearInterval(interval);}},duration / (text.length * 10),);return () => clearInterval(interval);}, [text, duration, trigger, animateOnLoad]);return (<divclassName="overflow-hidden py-2 flex cursor-default scale-100"onMouseEnter={triggerAnimation}><AnimatePresence mode="wait">{displayText.map((letter, i) => (<motion.h1key={i}className={cn("font-mono", letter === " " ? "w-3" : "", className)}{...framerProps}>{letter.toUpperCase()}</motion.h1>))}</AnimatePresence></div>);}
Hyper Text
Prop | Type | Default | Description |
---|---|---|---|
className | string | undefined | Optional class name to apply custom styling. |
duration | number | 800 | The duration (in ms) for the animation cycle. |
text | string | "" | The text to animate. |
framerProps | Variants | opacity and y values | Framer Motion props to customize animation transitions (initial, animate, exit). |
animateOnLoad | boolean | true | If true, plays the animation on initial load; if false, only triggers on hover. |