Component

Scramble

See on GitHub

A GSAP registered effect that decodes text with staggered character-by-character reveal animation. Weighted character sets and per-character jittered timing for an organic feel.

'use client'

import * as React from 'react'
import { ScrambleButton } from '@/components/scramble-button'
import { Switch } from '@/components/ui/switch'

function ScrambleButtonDemo() {
  const [scrambled, setScrambled] = React.useState(false)

  return (
    <div className="flex min-h-48 flex-col items-center justify-center gap-8 overflow-hidden p-8 font-mono">
      <div className="flex flex-col items-center gap-3 sm:flex-row">
        <ScrambleButton
          text="GET STARTED"
          scramble={scrambled}
          variant="default"
        />
        <ScrambleButton
          text="LEARN MORE"
          scramble={scrambled}
          chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
          variant="secondary"
        />
        <ScrambleButton
          text="SUBSCRIBE"
          scramble={scrambled}
          chars="01"
          variant="outline"
        />
      </div>

      {/* Mobile fallback: switch to trigger scramble */}
      <label className="flex cursor-pointer items-center gap-3 sm:hidden">
        <Switch checked={scrambled} onCheckedChange={setScrambled} />
        <span className="text-muted-foreground text-xs tracking-wider uppercase">
          Toggle scramble
        </span>
      </label>
    </div>
  )
}

export default ScrambleButtonDemo

Installation

pnpm dlx shadcn@latest add @joyco/scramble

Usage

Import the effect file to register it, then use gsap.effects.scramble() on any element:

import gsap from 'gsap'
import '@/registry/lib/gsap/effects/scramble'
 
// Scramble an element's text
gsap.effects.scramble('.heading', {
  text: 'DECODED TEXT',
  duration: 0.8,
})

On a timeline

The effect has extendTimeline: true, so you can chain it:

const tl = gsap.timeline()
tl.scramble('.line-1', { text: 'SYSTEM ONLINE' }).scramble(
  '.line-2',
  { text: 'ALL MODULES LOADED' },
  '+=0.2'
)

Custom character sets

Repeated characters increase their probability, creating visual breathing room:

// Hacker terminal (default) — underscores add visual pauses
gsap.effects.scramble(el, { chars: '!<>-_\\/[]{}—=+*^?#________' })
 
// Clean uppercase
gsap.effects.scramble(el, { chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' })
 
// Binary
gsap.effects.scramble(el, { chars: '01' })
 
// Block drawing
gsap.effects.scramble(el, { chars: '░▒▓█▀▄■□▪▫●○◆◇◈' })

Config

PropTypeDefaultDescription
textstringElement's textContentThe final text to reveal
charsstring!<>-_\\/[]{}—=+*^?#________Character set used for scrambling
durationnumber0.5Duration in seconds. 0 = auto-scale with text length
easestring'none'GSAP ease string
cyclesnumber2Randomization cycles per character before resolving (higher = more chaotic)
chancenumber1Probability (0–1) that each character scrambles
overflowbooleantrueShow all character positions from the start rather than growing in
ignoreReducedMotionbooleanfalseSkip prefers-reduced-motion check

Related Components

Maintainers
Downloads
0Total
0 downloads today