Join our Discord Community

React Shuffle Text Effect

Advanced GSAP-powered text shuffling animation with character-level transformations, scroll triggers, and customizable reveal patterns. Perfect for dynamic reveals.

Want to create shuffling text animations?

Join our Discord community for help from other developers.


Most text reveal animations use simple fades or slides that don't capture the mechanical, slot-machine-like feeling of characters shuffling into place. This component creates sophisticated character-level shuffling effects using GSAP's SplitText plugin with customizable directions, timing, and reveal patterns.

GSAP-powered character shuffling

Text that shuffles characters horizontally before revealing the final message:

Loading component...

Built with TypeScript for React applications, using GSAP's SplitText plugin and ScrollTrigger for high-performance character-level animations with precise control over shuffle direction, timing, and scrambling effects.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/shuffle.json
npx shadcn@latest add https://www.shadcn.io/registry/shuffle.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/shuffle.json
bunx shadcn@latest add https://www.shadcn.io/registry/shuffle.json

Usage

import Shuffle from "@/components/text/shuffle";

<div className="flex items-center justify-center min-h-screen w-full p-4 sm:p-8">
  <div className="text-center">
    <Shuffle
      text="SHADCN"
      shuffleDirection="right"
      duration={0.5}
      animationMode="evenodd"
      shuffleTimes={2}
      ease="power3.out"
      stagger={0.05}
      threshold={0.1}
      triggerOnce={false}
      triggerOnHover={true}
      respectReducedMotion={true}
      className="text-foreground"
      style={{
        fontSize: 'clamp(2rem, 8vw, 4rem)',
        fontFamily: 'inherit'
      }}
    />
  </div>
</div>

Why simple reveals aren't dynamic enough

Traditional text animations use basic opacity or position changes—approaches that don't create the mechanical, satisfying feeling of characters physically shuffling into position. Static reveals lack the kinetic energy and visual interest that makes shuffling effects compelling.

This React component uses GSAP's SplitText to break text into individual characters, then creates horizontal shuffling animations where characters slide into their final positions. Multiple shuffle cycles, scrambling characters, and customizable directions create slot-machine-like reveals that feel mechanical and engaging.

The key insight: character-level shuffling feels more satisfying than word-level animations. When individual letters move horizontally through multiple positions before settling, it creates more convincing mechanical animation than simple fades or slides.

Features

  • Advanced GSAP SplitText integration with character-level manipulation and horizontal sliding animations
  • Multiple shuffle cycles with customizable character scrambling and randomization between shuffles
  • Flexible trigger system supporting scroll-based reveals, hover interactions, and one-time animations
  • Even/odd stagger patterns for alternating character timing and sophisticated reveal sequences
  • Color transition support with customizable from/to colors synchronized with shuffle animations
  • Accessibility-first design respecting reduced motion preferences and semantic HTML structure
  • Free open source component compatible with Next.js and shadcn/ui design systems

API Reference

Shuffle

GSAP-powered text shuffling component with character-level animations.

PropTypeDefaultDescription
textstring-Text content to shuffle
classNamestring''Additional CSS classes
styleReact.CSSProperties{}Inline styles
shuffleDirection'left' | 'right''right'Character slide direction
durationnumber0.35Animation duration in seconds
maxDelaynumber0Maximum random delay for random mode
easestring | function'power3.out'GSAP easing curve
thresholdnumber0.1Scroll trigger threshold (0-1)
rootMarginstring'-100px'Scroll trigger margin
tagHTMLElement'p'HTML tag to render
textAlignCSS property'center'Text alignment
onShuffleCompletefunction-Callback when shuffle completes
shuffleTimesnumber1Number of shuffle cycles
animationMode'random' | 'evenodd''evenodd'Character stagger pattern
loopbooleanfalseEnable continuous looping
loopDelaynumber0Delay between loop cycles
staggernumber0.03Delay between character animations
scrambleCharsetstring''Characters to use for scrambling
colorFromstring-Starting color for transitions
colorTostring-Ending color for transitions
triggerOncebooleantrueTrigger animation only once
respectReducedMotionbooleantrueRespect accessibility preferences
triggerOnHoverbooleantrueEnable hover re-triggering

Animation Modes

Character stagger pattern options:

ModeBehaviorBest For
evenoddAlternating even/odd character timingSmooth, wave-like reveals
randomRandom delays within maxDelayChaotic, scattered reveals

Shuffle Directions

Character movement patterns:

DirectionEffectVisual Result
rightCharacters slide in from leftLeft-to-right mechanical feeling
leftCharacters slide in from rightRight-to-left reverse effect

Common gotchas

GSAP SplitText license: SplitText is a premium GSAP plugin requiring a license for commercial use. Ensure you have proper licensing before deploying to production environments.

Font loading timing: The component waits for fonts to load before initializing. Custom fonts might cause delays in animation start. Consider preloading fonts or using font-display: swap for better performance.

Performance with long text: Each character creates multiple DOM elements for shuffling. Very long text (50+ characters) might impact performance. Consider breaking long text into multiple components.

Responsive sizing conflicts: The component uses fixed character widths for shuffling. Responsive font sizes might cause layout issues during animation. Test across different screen sizes carefully.

Scroll trigger conflicts: Multiple shuffle components might interfere with each other's scroll triggers. Ensure proper spacing and unique trigger points for optimal performance.

Questions developers actually ask