Components

Velocity Morph

A high-velocity text morphing component with smooth blur, scale, and slide animations.

Last updated on

Edit on GitHub
"use client";
 
import { VelocityMorph } from "@/components/ui/velocity-morph";
 
export function VelocityMorphDemo() {
  return (
    <div className="flex items-center justify-center">
      <VelocityMorph
        texts={["Hello", "World", "Velocity", "Morph"]}
        className="font-bold text-4xl text-foreground"
      />
    </div>
  );
}

Examples

Variants

"use client";
 
import { VelocityMorph } from "@/components/ui/velocity-morph";
 
export function VelocityMorphCustomDemo() {
  return (
    <div className="flex flex-col items-center justify-center gap-8">
      <div className="text-center">
        <h3 className="mb-4 font-semibold text-lg">Fast Morphing</h3>
        <VelocityMorph
          texts={["CODE", "BUILD", "DEPLOY", "SCALE"]}
          interval={1500}
          className="font-mono text-2xl text-primary"
        />
      </div>
 
      <div className="text-center">
        <h3 className="mb-4 font-semibold text-lg">Slow Morphing</h3>
        <VelocityMorph
          texts={["DESIGN", "CREATE", "INNOVATE", "INSPIRE"]}
          interval={5000}
          className="font-bold text-3xl text-destructive"
        />
      </div>
    </div>
  );
}

Installation

CLI

npx shadcn@latest add "https://jolyui.dev/r/velocity-morph"

Manual

Install the following dependencies:

npm install motion

Copy and paste the following code into your project. component/ui/velocity-morph.tsx

import { AnimatePresence, motion } from "motion/react";
import * as React from "react";
import { cn } from "@/lib/utils";
 
interface VelocityMorphProps {
  texts: string[];
  className?: string;
  interval?: number;
}
 
const VelocityMorph = React.forwardRef<HTMLDivElement, VelocityMorphProps>(
  ({ texts, className, interval = 3000 }, ref) => {
    const [currentIndex, setCurrentIndex] = React.useState(0);
 
    React.useEffect(() => {
      const timer = setInterval(() => {
        setCurrentIndex((prev) => (prev + 1) % texts.length);
      }, interval);
 
      return () => clearInterval(timer);
    }, [interval, texts.length]);
 
    return (
      <div
        ref={ref}
        className={cn(
          "relative overflow-hidden whitespace-nowrap p-2",
          className,
        )}
      >
        <AnimatePresence mode="popLayout">
          <motion.div
            key={currentIndex}
            initial={{
              y: 40,
              opacity: 0,
              filter: "blur(10px)",
              scale: 0.8,
            }}
            animate={{
              y: 0,
              opacity: 1,
              filter: "blur(0px)",
              scale: 1,
            }}
            exit={{
              y: -40,
              opacity: 0,
              filter: "blur(10px)",
              scale: 0.8,
            }}
            transition={{
              duration: 0.4,
              ease: [0.16, 1, 0.3, 1],
            }}
          >
            {texts[currentIndex]}
          </motion.div>
        </AnimatePresence>
      </div>
    );
  },
);
 
VelocityMorph.displayName = "VelocityMorph";
 
export { VelocityMorph };

API Reference

Prop

Type

Notes

  • Uses motion/react for high-velocity animations with blur and scale effects
  • Automatically cycles through texts at specified intervals
  • Supports custom CSS classes for styling
  • Animation includes vertical movement, opacity, blur, and scale transitions
  • Perfect for hero sections, testimonials, or dynamic content with dramatic effects

How is this guide?

On this page