Text animations

Color Cycle Text

A self-contained component that animates a span of text by cycling through a given array of colors.

Innovate.Create.Inspire.

Our new platform provides real-time updates to keep you perfectly in sync with your team.

Typographic Styling
Style with standard Tailwind CSS classes.
Heavily Styled Text
Interactive States
Responds to user interaction like hover.
Hover Over Me

Dynamic Colors

Installation

CLI

Installation via the CLI is coming soon. For now, please follow the manual installation instructions below.

Manual

  1. Install the following dependencies:
npm install gsap @gsap/react
yarn add gsap @gsap/react
pnpm add gsap @gsap/react
  1. Copy and paste the following code into your project.
'use client';

import React, { useRef, useState, useEffect } from 'react';
import { useGSAP } from '@gsap/react';
import gsap from 'gsap';
import { cn } from '@/lib/utils';

/**
 * A curated list of common GSAP easing functions to provide autocompletion.
 */
type GsapEase =
  | 'none'
  | 'power1'
  | 'power1.in'
  | 'power1.out'
  | 'power1.inOut'
  | 'power2'
  | 'power2.in'
  | 'power2.out'
  | 'power2.inOut'
  | 'power3'
  | 'power3.in'
  | 'power3.out'
  | 'power3.inOut'
  | 'power4'
  | 'power4.in'
  | 'power4.out'
  | 'power4.inOut'
  | 'back'
  | 'back.in'
  | 'back.out'
  | 'back.inOut'
  | 'elastic'
  | 'elastic.in'
  | 'elastic.out'
  | 'elastic.inOut'
  | 'bounce'
  | 'bounce.in'
  | 'bounce.out'
  | 'bounce.inOut'
  | 'circ'
  | 'circ.in'
  | 'circ.out'
  | 'circ.inOut'
  | 'expo'
  | 'expo.in'
  | 'expo.out'
  | 'expo.inOut'
  | 'sine'
  | 'sine.in'
  | 'sine.out'
  | 'sine.inOut';

interface ColorCycleTextProps extends React.HTMLAttributes<HTMLSpanElement> {
  /** The text content to display and animate. */
  text: string;
  /** An array of CSS color strings to cycle through. Must contain at least two colors for the effect to run. */
  colors: string[];
  /** The duration of the color transition in seconds. */
  duration?: number;
  /**
   * The GSAP easing function for the animation. Provides autocompletion for common eases
   * but also accepts any custom GSAP ease string.
   */
  ease?: GsapEase | (string & {});
}

/**
 * A self-contained component that animates a span of text by cycling through a given array of colors.
 * It manages its own animation state locally without external dependencies.
 */
const ColorCycleText = React.forwardRef<HTMLSpanElement, ColorCycleTextProps>(
  (
    {
      text,
      colors,
      duration = 0.8,
      ease = 'power1.inOut',
      className,
      ...props
    },
    ref
  ) => {
    const textRef = useRef<HTMLSpanElement>(null);
    const [currentColorIndex, setCurrentColorIndex] = useState(0);

    useEffect(() => {
      setCurrentColorIndex(0);
    }, [colors.length]);

    useGSAP(
      () => {
        if (!textRef.current || colors.length < 2) {
          if (textRef.current) {
            gsap.set(textRef.current, { color: colors || 'inherit' });
          }
          return;
        }

        gsap.to(textRef.current, {
          color: colors[currentColorIndex],
          duration,
          ease,
          onComplete: () => {
            setCurrentColorIndex(
              (prevIndex) => (prevIndex + 1) % colors.length
            );
          },
        });
      },
      {
        scope: textRef,
        dependencies: [currentColorIndex, colors, duration, ease],
      }
    );

    return (
      <span
        ref={textRef}
        className={cn('inline-block', className)}
        style={{ color: colors || 'inherit', ...props.style }}
        {...props}
      >
        {text}
      </span>
    );
  }
);

ColorCycleText.displayName = 'ColorCycleText';

export { ColorCycleText };

Usage

Import the component and provide it with text and an array of colors.

import { ColorCycleText } from '@/components/ui/color-cycle-text';

export default function MyComponent() {
  const brandColors = ['#6366F1', '#EC4899', '#F59E0B'];
  const statusColors = ['#22C55E', '#FBBF24', '#EF4444'];

  return (
    <h1 className='text-4xl font-bold'>
      Build
      <ColorCycleText
        text=' beautiful '
        colors={brandColors}
        className='text-5xl'
      />
      and
      <ColorCycleText
        text=' dynamic '
        colors={statusColors}
        duration={2}
        ease='bounce.out'
        className='text-5xl'
      />
      interfaces.
    </h1>
  );
}

Props

This component accepts all standard <span> attributes like className and style.

PropTypeDefaultDescription
textstring(required)The text content to display and animate.
colorsstring[](required)An array of CSS color strings to cycle through.
durationnumber0.8The duration of the color transition in seconds.
easeGsapEase | (string & {})'power1.inOut'The GSAP easing function for the animation. Provides autocompletion and accepts custom ease strings.