Installation
Examples
Letter-by-Letter with Gradient
Animates each letter individually from the bottom with a gradient text effect — ideal for hero headings.
Custom Multi-Step Keyframes
Uses custom animationFrom and animationTo props to define a 3-step keyframe animation with heavier initial blur and a subtle bounce.
Usage
import BlurText from "@/components/motionx/blur-text";Basic heading
<BlurText
text="Welcome to MotionX"
className="text-4xl font-bold"
delay={150}
animateBy="words"
/>Letter-by-letter hero
<BlurText
text="Premium Design"
className="text-6xl font-extrabold"
delay={50}
animateBy="letters"
direction="bottom"
/>Custom keyframes
<BlurText
text="Custom Animation"
className="text-3xl"
animationFrom={{ filter: "blur(15px)", opacity: 0, y: -80 }}
animationTo={[
{ filter: "blur(8px)", opacity: 0.3, y: 10 },
{ filter: "blur(2px)", opacity: 0.7, y: -5 },
{ filter: "blur(0px)", opacity: 1, y: 0 },
]}
stepDuration={0.5}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | "" | The text content to animate |
delay | number | 200 | Stagger delay between elements in milliseconds |
className | string | "" | Additional CSS classes for custom styling |
animateBy | "words" | "letters" | "words" | Animate by word or letter granularity |
direction | "top" | "bottom" | "top" | Direction the text animates from |
threshold | number | 0.1 | IntersectionObserver visibility threshold (0-1) |
rootMargin | string | "0px" | IntersectionObserver root margin |
animationFrom | Record<string, string | number> | Blur + offset based on dir | Custom starting keyframe values |
animationTo | Record<string, string | number>[] | Two-step blur-to-clear | Array of keyframe steps to animate through |
easing | Easing | Easing[] | Linear | Motion easing function(s) |
onAnimationComplete | () => void | undefined | Callback fired when the last element finishes animating |
stepDuration | number | 0.35 | Duration of each keyframe step in seconds |
Animation Details
Scroll-triggered
The animation starts automatically when the component enters the viewport using IntersectionObserver. Once triggered, the observer disconnects to prevent re-animation.
Word vs Letter Mode
animateBy="words"— Splits text on spaces. Each word is an animated unit. Best for headings and short phrases.animateBy="letters"— Splits text into individual characters. Creates a more dramatic, cinematic effect.
Custom Keyframes
The component supports multi-step keyframe animations. Provide animationFrom for the initial state, and animationTo as an array of intermediate + final states:
// 3-step animation: blur(15px) → blur(8px) → blur(2px) → blur(0px)
animationFrom={{ filter: "blur(15px)", opacity: 0, y: -80 }}
animationTo={[
{ filter: "blur(8px)", opacity: 0.3, y: 10 },
{ filter: "blur(2px)", opacity: 0.7, y: -5 },
{ filter: "blur(0px)", opacity: 1, y: 0 },
]}