Docs
Motion Text

Motion Text

Text that animates character by character with various effects.

Character by Character Fade In
Individual Character Glitch Effect
Characters Sliding One By One

Installation

Copy and paste the following code into your project.

components/ui/motion-text.tsx

import React from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
 
interface MotionTextProps {
  text: string;
  className?: string;
  effect?: "fade" | "slide" | "glitch";
  duration?: number;
  delay?: number;
  stagger?: number;
  color?: string;
  fontSize?: string | number;
}
 
type VariantType = {
  initial: any;
  animate: any;
  transition?: {
    duration?: number;
    repeat?: number;
    repeatDelay?: number;
    delay?: number;
    ease?: string;
  };
};
 
const effectVariants: Record<string, (index: number) => VariantType> = {
  fade: (index: number) => ({
    initial: { opacity: 0, y: 20 },
    animate: { opacity: 1, y: 0 },
    transition: {
      duration: 0.3,
      delay: index * 0.1,
    },
  }),
  slide: (index: number) => ({
    initial: { x: -20, opacity: 0 },
    animate: { x: 0, opacity: 1 },
    transition: {
      duration: 0.3,
      delay: index * 0.08,
    },
  }),
  glitch: (index: number) => ({
    initial: { x: 0 },
    animate: {
      x: [0, -3, 3, -3, 3, 0],
      y: [0, 2, -2, 2, -2, 0],
      filter: [
        "none",
        "brightness(150%) contrast(150%)",
        "none",
        "brightness(150%) contrast(150%)",
        "none",
      ],
    },
    transition: {
      duration: 0.3,
      repeat: Infinity,
      repeatDelay: 4,
      delay: index * 0.05,
    },
  }),
};
 
export function MotionText({
  text,
  className,
  effect = "fade",
  duration = 0.3,
  delay = 0,
  stagger = 0.05,
  color,
  fontSize,
}: MotionTextProps) {
  const characters = text.split("");
 
  return (
    <span className={cn("inline-block", className)} style={{ color, fontSize }}>
      {characters.map((char, index) => {
        const variant = effectVariants[effect](index);
 
        return (
          <motion.span
            key={index}
            initial={variant.initial}
            animate={variant.animate}
            transition={variant.transition}
            className="relative inline-block"
            style={{
              willChange: "transform",
              backfaceVisibility: "hidden",
            }}
          >
            {char === " " ? "\u00A0" : char}
          </motion.span>
        );
      })}
    </span>
  );
}

Update the import paths to match your project setup.

import MotionText from "@/components/ui/motion-text";

Usage

import MotionText from "@/components/ui/motion-text";
 
export default function Example() {
  return (
    <div className="space-y-8">
      {/* Fade Effect */}
      <MotionText
        text="Character by Character Fade In"
        effect="fade"
        stagger={0.1}
      />
 
      {/* Glitch Effect */}
      <MotionText
        text="Individual Character Glitch Effect"
        effect="glitch"
        stagger={0.02}
      />
 
      {/* Slide Effect */}
      <MotionText
        text="Characters Sliding One By One"
        effect="slide"
        stagger={0.08}
      />
    </div>
  );
}

Props

NameTypeDefaultDescription
textstringThe text content to animate.
effect`"fade""fade"The animation effect to apply to each character.
durationnumber0.3Duration of the animation in seconds.
delaynumber0Initial delay before starting the animation.
staggernumber0.05Delay between each character's animation.
colorstringText color. Accepts any valid CSS color value.
fontSizestringFont size. Accepts any valid CSS font-size value.
classNamestringAdditional CSS classes to apply to the text container.

Examples

Fade Effect

The fade effect smoothly transitions each character from invisible to visible with a subtle upward movement.

<MotionText text="Character by Character Fade In" effect="fade" stagger={0.1} />

Glitch Effect

The glitch effect creates a cyberpunk-style animation with rapid position shifts and contrast changes.

<MotionText
  text="Individual Character Glitch Effect"
  effect="glitch"
  stagger={0.02}
/>

Slide Effect

The slide effect makes characters appear by sliding them in from the left.

<MotionText
  text="Characters Sliding One By One"
  effect="slide"
  stagger={0.08}
/>

Customization

You can customize the appearance of the text using standard CSS classes or inline styles:

<MotionText
  text="Custom Styled Text"
  effect="fade"
  className="font-bold text-5xl bg-linear-to-r from-purple-500 to-pink-500 text-transparent bg-clip-text"
  stagger={0.1}
/>

Each animation effect can be fine-tuned using the duration and stagger props to achieve the desired timing and flow.