microck/gsap-skills · Archived

gsap-text

Use when implementing text animations, text effects, character/word/line animations, text reveals, scrambling effects, or using SplitText, TextPlugin, ScrambleTextPlugin.

First seen Apr 2, 2026

Installation

$ npx skills add microck/gsap-skills --skill gsap-text

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from microck/gsap-skills · top by installs.

npx skills add microck/gsap-skills

Browse all from microck/gsap-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch master
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 12,174 B
  • docs SUMMARY.md 187 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 10 installs

SKILL.md

GSAP Text Animations

GSAP provides powerful tools for text animation through SplitText, TextPlugin, and ScrambleTextPlugin. Create dramatic reveals, highlights, and interactive text effects.

Installation

SplitText (formerly members-only; now included)

npm install gsap
import { SplitText } from 'gsap/SplitText'
gsap.registerPlugin(SplitText)

TextPlugin (Free)

import { TextPlugin } from 'gsap/TextPlugin'
gsap.registerPlugin(TextPlugin)

ScrambleTextPlugin (formerly members-only; now included)

import { ScrambleTextPlugin } from 'gsap/ScrambleTextPlugin'
gsap.registerPlugin(ScrambleTextPlugin)

SplitText

Basic Setup

gsap.registerPlugin(SplitText)

// Create split text
const split = new SplitText('#myText', {
  type: 'chars,words,lines'  // What to split
})

// Access split elements
console.log(split.chars)   // Array of char elements
console.log(split.words)   // Array of word elements
console.log(split.lines)   // Array of line elements

Split Types

// Split only characters
const split = new SplitText('#myText', {
  type: 'chars'
})

// Split words
const split = new SplitText('#myText', {
  type: 'words'
})

// Split lines
const split = new SplitText('#myText', {
  type: 'lines'
})

// Multiple types
const split = new SplitText('#myText', {
  type: 'chars,words,lines'
})

// Split all
const split = new SplitText('#myText', {
  type: 'chars,words,lines'
})

Character Animations

const split = new SplitText('#heading', { type: 'chars' })

// Reveal characters
gsap.from(split.chars, {
  opacity: 0,
  y: 20,
  stagger: 0.05,
  duration: 0.5,
  ease: 'back.out(1.7)'
})

// Scale and rotate
gsap.from(split.chars, {
  opacity: 0,
  scale: 0,
  rotation: () => gsap.utils.random(-20, 20),
  stagger: 0.03,
  duration: 0.8,
  ease: 'elastic.out(1, 0.5)'
})

Word Animations

const split = new SplitText('#paragraph', { type: 'words' })

// Slide in words
gsap.from(split.words, {
  opacity: 0,
  x: -30,
  stagger: 0.1,
  duration: 0.6,
  ease: 'power2.out'
})

// Bounce effect
gsap.from(split.words, {
  opacity: 0,
  y: 50,
  stagger: {
    each: 0.15,
    from: 'center',
    ease: 'back.out(1.7)'
  },
  duration: 0.8
})

Line Animations

const split = new SplitText('#paragraph', { type: 'lines' })

// Reveal lines
gsap.from(split.lines, {
  opacity: 0,
  y: 50,
  stagger: 0.2,
  duration: 0.8,
  ease: 'power2.out'
})

// Slide from sides
gsap.from(split.lines, {
  opacity: 0,
  x: (i) => i % 2 === 0 ? -100 : 100,  // Alternate directions
  stagger: 0.15,
  duration: 0.7,
  ease: 'power2.out'
})

Combined Split Animations

const split = new SplitText('#text', { type: 'chars,words,lines' })

// Animate characters
gsap.from(split.chars, {
  opacity: 0,
  scale: 0.5,
  stagger: 0.02,
  duration: 0.5,
  ease: 'back.out(1.7)'
})

// Then animate words
gsap.from(split.words, {
  opacity: 0,
  y: 30,
  stagger: 0.1,
  duration: 0.5,
  ease: 'power2.out',
  delay: 0.8
})

Stagger Patterns

const split = new SplitText('#text', { type: 'chars' })

// From center
gsap.from(split.chars, {
  opacity: 0,
  scale: 0,
  stagger: {
    each: 0.02,
    from: 'center',
    ease: 'power2.out'
  },
  duration: 0.8
})

// From edges
gsap.from(split.chars, {
  opacity: 0,
  y: 20,
  stagger: {
    each: 0.02,
    from: 'edges',
    ease: 'power2.out'
  },
  duration: 0.6
})

// Grid pattern
gsap.from(split.chars, {
  opacity: 0,
  scale: 0,
  stagger: {
    each: 0.02,
    from: 'center',
    grid: [10, 5],  // 10 columns, 5 rows
    ease: 'power2.out'
  },
  duration: 0.8
})

Responsive Splits

// Auto-split on window resize
const split = new SplitText('#text', {
  type: 'chars,words',
  wordsClass: 'word',
  charsClass: 'char'
})

window.addEventListener('resize', () => {
  split.revert()
  new SplitText('#text', {
    type: 'chars,words',
    wordsClass: 'word',
    charsClass: 'char'
  })
})

// Or use matchMedia
const mm = gsap.matchMedia()

mm.add('(min-width: 768px)', () => {
  const split = new SplitText('#text', { type: 'chars' })
  gsap.from(split.chars, { opacity: 0, y: 20, stagger: 0.02 })
  return () => split.revert()
})

Cleanup

const split = new SplitText('#text', { type: 'chars' })

// Revert to original HTML
split.revert()

// Kill specific splits
split.chars.revert()

// Clear all splits
SplitText.revert()

ScrambleTextPlugin

Basic Scramble

gsap.registerPlugin(ScrambleTextPlugin)

gsap.to('#text', {
  duration: 2,
  scrambleText: {
    chars: 'upperCase',
    revealDelay: 0.5,
    speed: 0.3
  }
})

Custom Characters

gsap.to('#text', {
  duration: 2,
  scrambleText: {
    chars: '!<>-_\\/[]{}—=+*^?#________',
    speed: 0.2
  }
})

Text Change

gsap.to('#text', {
  duration: 2,
  scrambleText: {
    text: 'New Text Here',
    chars: 'XO',
    revealDelay: 0.3,
    speed: 0.4
  }
})

Reveal Pattern

gsap.to('#text', {
  duration: 3,
  scrambleText: {
    chars: '0123456789',
    revealDelay: 1,
    speed: 0.1
  }
})

Decode Effect

gsap.to('#secret', {
  duration: 4,
  scrambleText: {
    text: 'DECODED MESSAGE',
    chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
    revealDelay: 2,
    speed: 0.2
  }
})

Speed Control

gsap.to('#text', {
  duration: 2,
  scrambleText: {
    chars: 'upperCase',
    speed: 0.1,           // Slow scramble
    revealDelay: 1.5
  }
})

// Fast scramble
gsap.to('#text', {
  duration: 1,
  scrambleText: {
    chars: 'upperCase',
    speed: 0.8,           // Fast scramble
    revealDelay: 0.2
  }
})

Combined with SplitText

const split = new SplitText('#text', { type: 'chars' })

gsap.from(split.chars, {
  opacity: 0,
  scrambleText: {
    chars: 'XO',
    speed: 0.3,
    revealDelay: 0.5
  },
  stagger: 0.03,
  duration: 2,
  ease: 'power2.out'
})

TextPlugin

Basic Text Change

gsap.registerPlugin(TextPlugin)

gsap.to('#text', {
  duration: 1,
  text: 'New text content'
})

Incremental Text

gsap.to('#counter', {
  duration: 2,
  text: {
    value: 1000,
    delimiter: '',
    padZeroes: true
  }
})

Array Text

const phrases = ['Hello', 'World', 'GSAP', 'Text']

gsap.to('#text', {
  duration: 3,
  text: {
    value: phrases,
    delimiter: ' ',
    newClass: 'new-text',
    oldClass: 'old-text'
  }
})

ScrollTrigger + Text

Scroll Reveal

gsap.registerPlugin(ScrollTrigger, SplitText)

const split = new SplitText('#text', { type: 'chars' })

gsap.from(split.chars, {
  opacity: 0,
  y: 30,
  stagger: 0.02,
  scrollTrigger: {
    trigger: '#text',
    start: 'top 80%',
    toggleActions: 'play none none reverse'
  }
})

Scrolling Highlight

const split = new SplitText('#text', { type: 'chars' })

gsap.to(split.chars, {
  color: '#ff0000',
  scale: 1.2,
  stagger: 0.01,
  scrollTrigger: {
    trigger: '#text',
    start: 'top center',
    end: 'bottom center',
    scrub: true
  }
})

Scroll Scramble

gsap.to('#text', {
  duration: 2,
  scrambleText: {
    text: 'Scrambled Text',
    chars: 'XO',
    speed: 0.3
  },
  scrollTrigger: {
    trigger: '#text',
    start: 'top 80%',
    toggleActions: 'play none none reverse'
  }
})

Text Effects Patterns

Typewriter Effect

const split = new SplitText('#text', { type: 'chars' })

gsap.from(split.chars, {
  opacity: 0,
  x: -10,
  stagger: 0.05,
  duration: 0.1,
  ease: 'none'
})

Wave Effect

const split = new SplitText('#text', { type: 'chars' })

gsap.from(split.chars, {
  y: -50,
  opacity: 0,
  stagger: {
    each: 0.03,
    from: 'center',
    ease: 'sine.out'
  },
  duration: 1
})

Explosion Effect

const split = new SplitText('#text', { type: 'chars' })

gsap.from(split.chars, {
  opacity: 0,
  scale: 0,
  x: () => gsap.utils.random(-200, 200),
  y: () => gsap.utils.random(-200, 200),
  rotation: () => gsap.utils.random(-180, 180),
  stagger: {
    each: 0.01,
    from: 'random',
    ease: 'power2.out'
  },
  duration: 1.5
})

Glitch Effect

const split = new SplitText('#text', { type: 'chars' })

gsap.to(split.chars, {
  x: () => gsap.utils.random(-5, 5),
  y: () => gsap.utils.random(-5, 5),
  stagger: {
    each: 0.02,
    from: 'random',
    ease: 'steps(3)'
  },
  duration: 0.3,
  repeat: 3,
  yoyo: true,
  onComplete: () => {
    gsap.to(split.chars, { x: 0, y: 0, duration: 0.1 })
  }
})

Magnetic Text

const split = new SplitText('#text', { type: 'chars' })

document.querySelectorAll(split.chars).forEach(char => {
  gsap.to(char, {
    x: 0,
    y: 0,
    duration: 0.5,
    ease: 'elastic.out(1, 0.3)'
  })

  char.addEventListener('mouseenter', () => {
    gsap.to(char, {
      x: gsap.utils.random(-10, 10),
      y: gsap.utils.random(-10, 10),
      duration: 0.2
    })
  })
})

Performance Tips

Optimize Splits

// ❌ Split every character unnecessarily
const split = new SplitText('#long-text', { type: 'chars,words,lines' })

// ✅ Split only what you need
const split = new SplitText('#long-text', { type: 'words' })

Revert When Done

const split = new SplitText('#text', { type: 'chars' })

gsap.from(split.chars, {
  opacity: 0,
  y: 20,
  stagger: 0.02,
  duration: 0.5,
  onComplete: () => {
    split.revert()  // Clean up when animation done
  }
})

Use matchMedia

// ❌ Always split chars
const split = new SplitText('#text', { type: 'chars' })

// ✅ Only split on large screens
const mm = gsap.matchMedia()

mm.add('(min-width: 768px)', () => {
  const split = new SplitText('#text', { type: 'chars' })
  gsap.from(split.chars, { opacity: 0, y: 20, stagger: 0.02 })
  return () => split.revert()
})

Common Mistakes

1. Forgetting Revert

// ❌ Memory leaks
const split = new SplitText('#text', { type: 'chars' })
// Never revert

// ✅ Always revert
const split = new SplitText('#text', { type: 'chars' })
// ... animation ...
split.revert()

2. Splitting Too Much

// ❌ Split everything
const split = new SplitText('#text', { type: 'chars,words,lines' })

// ✅ Split only needed parts
const split = new SplitText('#text', { type: 'chars' })

3. Wrong Scramble Speed

// ❌ Too slow, unreadable
gsap.to('#text', {
  duration: 5,
  scrambleText: {
    chars: 'upperCase',
    speed: 0.05
  }
})

// ✅ Readable speed
gsap.to('#text', {
  duration: 2,
  scrambleText: {
    chars: 'upperCase',
    speed: 0.3
  }
})

Best Practices

  1. Revert splits - Clean up after animations
  2. Use matchMedia - Responsive text animations
  3. Choose right split type - Chars, words, or lines based on effect
  4. Control stagger - Don't make it too slow or too fast
  5. Combine with ScrollTrigger - Create scroll-based text reveals
  6. Test performance - Long text with char splits can be heavy
  7. Use appropriate speed - Scramble should be readable
  8. Consider accessibility - Ensure text remains accessible

Quick Reference

Feature Method
Split chars new SplitText(target, { type: 'chars' })
Split words new SplitText(target, { type: 'words' })
Split lines new SplitText(target, { type: 'lines' })
Revert split split.revert()
Scramble text gsap.to(target, { scrambleText: { chars, speed } })
Change text gsap.to(target, { text: 'new text' })
Stagger chars gsap.from(split.chars, { stagger: 0.02 })
Scroll reveal gsap.from(split.chars, { scrollTrigger: { ... } })