Docs
Ghost Text

Ghost Text

A text animation component that transitions between blurred and crisp states, with dark and light mode support.

Creativitybloomsinthedigitalgarden

Installation

Copy and paste the following code into your project.

components/ui/ghost-text.tsx

import React from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
 
interface GhostTextProps {
  text: string;
  className?: string;
  duration?: number;
  wordDelay?: number;
  textColor?: string;
  blurColor?: string;
  blurRadius?: number;
  fontSize?: number;
  fontWeight?: number | string;
  timings?: number[];
  sequential?: boolean;
}
 
export function GhostText({
  text,
  className,
  duration = 10,
  wordDelay = 0.1,
  textColor,
  blurColor,
  blurRadius = 100,
  fontSize = 400,
  fontWeight = 700,
  timings = [0, 0.05, 0.15, 0.2, 0.8, 0.95, 1],
  sequential = true,
}: GhostTextProps) {
  const words = text.split(" ");
 
  return (
    <p
      className={cn("text-center", className)}
      style={{
        fontSize: `${fontSize}%`,
        fontWeight,
        color: textColor,
      }}
    >
      {words.map((word, index) => (
        <motion.span
          key={index}
          style={{
            ["--blur-color" as string]: "rgb(var(--text-color))",
          }}
          className="mx-1 inline-block text-transparent [--text-color:15_23_42] dark:[--text-color:255_255_255]"
          animate={{
            opacity: [0, 0, 1, 1, 1, 1, 0],
            textShadow: [
              `0 0 ${blurRadius}px ${blurColor || "var(--blur-color)"}`,
              `0 0 ${blurRadius * 0.9}px ${blurColor || "var(--blur-color)"}`,
              `0 0 0px ${blurColor || "var(--blur-color)"}`,
              `0 0 0px ${blurColor || "var(--blur-color)"}`,
              `0 0 0px ${blurColor || "var(--blur-color)"}`,
              `0 0 ${blurRadius * 0.9}px ${blurColor || "var(--blur-color)"}`,
              `0 0 ${blurRadius}px ${blurColor || "var(--blur-color)"}`,
            ],
          }}
          transition={{
            duration,
            times: timings,
            ease: "easeOut",
            repeat: Infinity,
            delay: sequential ? index * wordDelay : 0,
          }}
        >
          {word}
        </motion.span>
      ))}
    </p>
  );
}

Update the import paths to match your project setup.

import GhostText from "@/components/ui/ghost-text";

Usage

import GhostText from "@/components/ui/ghost-text";
 
export default function Example() {
  return (
    <GhostText
      text="Creativity blooms in the digital garden"
      duration={10}
      wordDelay={0.1}
      blurRadius={100}
      fontSize={300}
      sequential={true}
    />
  );
}

Props

PropTypeDefaultDescription
textstringRequiredThe text to animate
classNamestring-Additional CSS classes
durationnumber10Duration of animation in seconds
wordDelaynumber0.1Delay between each word in seconds
textColorstringDark: white, Light: zinc-800Optional override for text color
blurColorstringSame as text colorOptional override for blur effect color
blurRadiusnumber100Maximum blur radius in pixels
fontSizenumber400Font size in percentage (e.g., 400 for 400%)
fontWeightnumber|string700Font weight
timingsnumber[][0, 0.05, 0.15, 0.2, 0.8, 0.95, 1]Custom timing array for animation keyframes
sequentialbooleantrueEnable sequential word animation

Examples

Basic Usage with Dark/Light Mode Support

<GhostText text="Adapts to theme" />

Custom Colors Override

<GhostText text="Custom colors" textColor="#00ff00" blurColor="#00ff00" />

Fast Animation

<GhostText text="Quick blur-sm" duration={5} wordDelay={0.05} blurRadius={50} />

Simultaneous Animation

<GhostText text="All at once" sequential={false} />

Large Text

<GhostText text="Big text" fontSize={600} blurRadius={150} />