ComponentsText Animations

Rotate Text

Word rotation animation for React. Smooth vertical flip transitions with spring physics. Great for hero headlines and dynamic taglines.

Last updated on

Edit on GitHub
"use client";
 
import { RotatingText } from "@/components/ui/rotate-text";
 
export function RotateTextDemo() {
  return (
    <div className="flex items-center justify-center">
      <RotatingText
        words={["Hello", "World", "Rotate", "Text"]}
        className="font-bold text-4xl text-foreground"
      />
    </div>
  );
}

Examples

Variants

"use client";
 
import { RotatingText } from "@/components/ui/rotate-text";
 
export function RotateTextCustomDemo() {
  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 Rotation</h3>
        <RotatingText
          words={["Code", "Build", "Deploy", "Scale"]}
          interval={1000}
          className="font-mono text-2xl text-primary"
        />
      </div>
 
      <div className="text-center">
        <h3 className="mb-4 font-semibold text-lg">Slow Rotation</h3>
        <RotatingText
          words={["Design", "Create", "Innovate", "Inspire"]}
          interval={4000}
          className="font-bold text-3xl text-destructive"
        />
      </div>
    </div>
  );
}

Installation

CLI

npx shadcn@latest add "https://jolyui.dev/r/rotate-text"

Manual

Install the following dependencies:

npm install motion

Copy and paste the following code into your project. component/ui/rotate-text.tsx

import { AnimatePresence, motion } from "motion/react";
import * as React from "react";
import { cn } from "@/lib/utils";
 
interface RotatingTextProps {
  words: string[];
  className?: string;
  interval?: number;
}
 
const RotatingText = React.forwardRef<HTMLSpanElement, RotatingTextProps>(
  ({ words, className, interval = 2000 }, ref) => {
    const [currentIndex, setCurrentIndex] = React.useState(0);
 
    React.useEffect(() => {
      const timer = setInterval(() => {
        setCurrentIndex((prev) => (prev + 1) % words.length);
      }, interval);
      return () => clearInterval(timer);
    }, [words.length, interval]);
 
    return (
      <span
        ref={ref}
        className={cn("relative inline-flex overflow-hidden", className)}
      >
        <AnimatePresence mode="popLayout">
          <motion.span
            key={currentIndex}
            initial={{ y: "100%", opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            exit={{ y: "-100%", opacity: 0 }}
            transition={{
              type: "spring",
              stiffness: 300,
              damping: 30,
            }}
            className="inline-block"
          >
            {words[currentIndex]}
          </motion.span>
        </AnimatePresence>
      </span>
    );
  },
);
RotatingText.displayName = "RotatingText";
 
export { RotatingText };

API Reference

Prop

Type

Notes

  • Uses motion/react for smooth spring animations
  • Automatically cycles through words at specified intervals
  • Supports custom CSS classes for styling
  • Animation includes vertical sliding and opacity transitions
  • Perfect for hero sections, testimonials, or dynamic content

How is this guide?

On this page