🎯

elite-gsap

🎯Skill

from rshvr/elite-web-design

VibeIndex|
What it does

Provides comprehensive GSAP animation techniques, covering ScrollTrigger, SplitText, SVG animations, and advanced web motion design with 100% free plugins.

πŸ“¦

Part of

rshvr/elite-web-design(7 items)

elite-gsap

Installation

npm installInstall npm package
npm install gsap
πŸ“– Extracted from docs: rshvr/elite-web-design
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

|

Overview

# Elite GSAP

The most powerful animation library for the web. All plugins now 100% free.

2026 Update: GSAP is Free

As of Webflow's acquisition, all GSAP plugins (including former "Club" plugins) are completely free for commercial use:

  • ScrollTrigger
  • SplitText
  • Flip
  • MorphSVG
  • DrawSVG
  • MotionPathPlugin
  • Physics2D
  • Inertia
  • CustomEase

No more licensing restrictions.

---

Quick Reference

| Topic | Reference File |

|-------|---------------|

| ScrollTrigger | [scrolltrigger.md](references/scrolltrigger.md) |

| SplitText | [splittext.md](references/splittext.md) |

| Flip plugin | [flip-plugin.md](references/flip-plugin.md) |

| MorphSVG & DrawSVG | [morphsvg-drawsvg.md](references/morphsvg-drawsvg.md) |

| Timelines | [timelines.md](references/timelines.md) |

| Framework integration | [framework-integration.md](references/framework-integration.md) |

---

Core Setup

Installation

```bash

npm install gsap

```

Plugin Registration

Register plugins once at app entry point:

```javascript

import gsap from 'gsap';

import { ScrollTrigger } from 'gsap/ScrollTrigger';

import { SplitText } from 'gsap/SplitText';

import { Flip } from 'gsap/Flip';

import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin';

import { MorphSVGPlugin } from 'gsap/MorphSVGPlugin';

import { MotionPathPlugin } from 'gsap/MotionPathPlugin';

gsap.registerPlugin(

ScrollTrigger,

SplitText,

Flip,

DrawSVGPlugin,

MorphSVGPlugin,

MotionPathPlugin

);

```

---

Context & Cleanup (CRITICAL)

Always use gsap.context() to scope animations. This prevents memory leaks in SPAs and component-based frameworks.

Vanilla JS

```javascript

// Create context scoped to a container

const ctx = gsap.context(() => {

// All animations and ScrollTriggers created here

// are automatically tracked

gsap.from('.hero-title', { opacity: 0, y: 50 });

gsap.from('.hero-description', { opacity: 0, y: 30, delay: 0.3 });

ScrollTrigger.create({

trigger: '.section',

start: 'top center',

onEnter: () => console.log('entered')

});

}, containerElement); // Scope to container

// Later: Clean up everything

ctx.revert(); // Reverts all animations and kills ScrollTriggers

```

Why This Matters

Without context:

  • Animations persist after component unmount
  • ScrollTriggers keep listening to removed elements
  • Memory leaks accumulate
  • SPA navigation breaks animations

With context:

  • Single revert() call cleans everything
  • Safe for React/Vue/Svelte components
  • No stale references

---

Essential Animation Patterns

Basic Tween

```javascript

// Animate TO a state

gsap.to('.element', {

x: 100,

opacity: 0.5,

duration: 1,

ease: 'power2.out'

});

// Animate FROM a state

gsap.from('.element', {

opacity: 0,

y: 50,

duration: 0.8,

ease: 'power3.out'

});

// FROM-TO for full control

gsap.fromTo('.element',

{ opacity: 0, y: 50 },

{ opacity: 1, y: 0, duration: 0.8 }

);

// Set immediately (no animation)

gsap.set('.element', { opacity: 1, y: 0 });

```

Stagger Animations

```javascript

// Basic stagger

gsap.from('.card', {

opacity: 0,

y: 30,

duration: 0.6,

stagger: 0.1 // 100ms between each

});

// Advanced stagger

gsap.from('.grid-item', {

opacity: 0,

scale: 0.8,

duration: 0.5,

stagger: {

each: 0.1,

from: 'center', // 'start', 'end', 'center', 'edges', 'random', or index

grid: [4, 6], // For grid layouts

axis: 'x' // 'x', 'y', or null for both

}

});

```

Easing

```javascript

// Power eases (most common)

gsap.to('.el', { x: 100, ease: 'power1.out' }); // Subtle

gsap.to('.el', { x: 100, ease: 'power2.out' }); // Balanced (recommended)

gsap.to('.el', { x: 100, ease: 'power3.out' }); // Snappy

gsap.to('.el', { x: 100, ease: 'power4.out' }); // Dramatic

// Ease directions

// .in - starts slow, accelerates

// .out - starts fast, decelerates (default)

// .inOut - slow at both ends

// Special eases

gsap.to('.el', { x: 100, ease: 'elastic.out(1, 0.3)' });

gsap.to('.el', { x: 100, ease: 'back.out(1.7)' });

gsap.to('.el', { x: 100, ease: 'bounce.out' });

// Custom ease

gsap.to('.el', { x: 100, ease: 'M0,0 C0.7,0 0.3,1 1,1' }); // Bezier

```

Callbacks

```javascript

gsap.to('.element', {

x: 100,

duration: 1,

onStart: () => console.log('Animation started'),

onUpdate: () => console.log('Frame update'),

onComplete: () => console.log('Animation complete'),

onReverseComplete: () => console.log('Reversed to start')

});

```

---

prefers-reduced-motion (CRITICAL)

Always respect user motion preferences:

```javascript

const mm = gsap.matchMedia();

mm.add('(prefers-reduced-motion: no-preference)', () => {

// Full animations

gsap.from('.hero', {

opacity: 0,

y: 50,

duration: 1,

ease: 'power3.out'

});

});

mm.add('(prefers-reduced-motion: reduce)', () => {

// Instant or simple fade

gsap.set('.hero', { opacity: 1, y: 0 });

// Or: gsap.from('.hero', { opacity: 0, duration: 0.3 });

});

```

See elite-accessibility skill for comprehensive patterns.

---

GPU-Accelerated Properties

For 60fps performance, only animate:

  • x, y (translateX, translateY)
  • xPercent, yPercent
  • scale, scaleX, scaleY
  • rotation, rotationX, rotationY
  • opacity

Never animate:

  • width, height
  • top, left, right, bottom
  • margin, padding
  • border-width

```javascript

// GOOD - GPU accelerated

gsap.to('.card', { x: 100, y: 50, scale: 1.1, rotation: 5, opacity: 0.8 });

// BAD - Causes reflows

gsap.to('.card', { width: 200, height: 200, marginLeft: 50 });

```

---

ScrollTrigger Quick Start

```javascript

import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

// Basic scroll-triggered animation

gsap.from('.section-content', {

opacity: 0,

y: 50,

duration: 1,

scrollTrigger: {

trigger: '.section',

start: 'top 80%', // When top of trigger hits 80% of viewport

end: 'bottom 20%',

toggleActions: 'play none none none',

// markers: true // Dev only

}

});

// Pinned section

ScrollTrigger.create({

trigger: '.sticky-section',

start: 'top top',

end: '+=100%',

pin: true,

pinSpacing: true

});

// Scrub animation (tied to scroll position)

gsap.to('.parallax-element', {

y: -100,

ease: 'none',

scrollTrigger: {

trigger: '.parallax-section',

start: 'top bottom',

end: 'bottom top',

scrub: true

}

});

```

See [scrolltrigger.md](references/scrolltrigger.md) for comprehensive patterns.

---

SplitText Quick Start

```javascript

import { SplitText } from 'gsap/SplitText';

gsap.registerPlugin(SplitText);

// Split text into characters

const split = new SplitText('.headline', {

type: 'chars,words,lines',

linesClass: 'line'

});

// Animate characters

gsap.from(split.chars, {

opacity: 0,

y: 50,

rotationX: -90,

stagger: 0.02,

duration: 0.8,

ease: 'power4.out'

});

// IMPORTANT: Revert when done (or on cleanup)

// split.revert();

```

See [splittext.md](references/splittext.md) for text animation patterns.

---

Flip Plugin Quick Start

```javascript

import { Flip } from 'gsap/Flip';

gsap.registerPlugin(Flip);

// Capture current state

const state = Flip.getState('.cards');

// Make DOM changes

container.appendChild(newCard);

// or

card.classList.toggle('expanded');

// or

filterCards();

// Animate the change

Flip.from(state, {

duration: 0.6,

ease: 'power2.inOut',

stagger: 0.05,

absolute: true, // Prevents layout shift during animation

onEnter: elements => gsap.from(elements, { opacity: 0, scale: 0.8 }),

onLeave: elements => gsap.to(elements, { opacity: 0, scale: 0.8 })

});

```

See [flip-plugin.md](references/flip-plugin.md) for layout animation patterns.

---

Timeline Quick Start

```javascript

const tl = gsap.timeline({

defaults: { duration: 0.8, ease: 'power3.out' }

});

tl.from('.hero-title', { opacity: 0, y: 50 })

.from('.hero-description', { opacity: 0, y: 30 }, '-=0.5') // Overlap

.from('.hero-cta', { opacity: 0, y: 20 }, '-=0.3')

.from('.hero-image', { opacity: 0, scale: 0.9 }, '<'); // Same time as previous

// Control

tl.play();

tl.pause();

tl.reverse();

tl.seek(0.5); // Jump to 0.5 seconds

tl.progress(0.5); // Jump to 50%

```

See [timelines.md](references/timelines.md) for orchestration patterns.

---

Common Patterns

Reveal on Scroll

```javascript

const mm = gsap.matchMedia();

mm.add('(prefers-reduced-motion: no-preference)', () => {

gsap.utils.toArray('.reveal').forEach(element => {

gsap.from(element, {

opacity: 0,

y: 40,

duration: 0.8,

ease: 'power3.out',

scrollTrigger: {

trigger: element,

start: 'top 85%',

toggleActions: 'play none none none'

}

});

});

});

```

Horizontal Scroll Section

```javascript

const mm = gsap.matchMedia();

mm.add('(prefers-reduced-motion: no-preference)', () => {

const panels = gsap.utils.toArray('.panel');

const wrapper = document.querySelector('.horizontal-wrapper');

gsap.to(panels, {

xPercent: -100 * (panels.length - 1),

ease: 'none',

scrollTrigger: {

trigger: wrapper,

pin: true,

scrub: 1,

snap: 1 / (panels.length - 1),

end: () => '+=' + wrapper.scrollWidth

}

});

});

```

Magnetic Button

```javascript

const button = document.querySelector('.magnetic-btn');

button.addEventListener('mousemove', (e) => {

const rect = button.getBoundingClientRect();

const x = e.clientX - rect.left - rect.width / 2;

const y = e.clientY - rect.top - rect.height / 2;

gsap.to(button, {

x: x * 0.3,

y: y * 0.3,

duration: 0.3,

ease: 'power2.out'

});

});

button.addEventListener('mouseleave', () => {

gsap.to(button, {

x: 0,

y: 0,

duration: 0.5,

ease: 'elastic.out(1, 0.3)'

});

});

```

Text Reveal with Mask

```javascript

const split = new SplitText('.headline', { type: 'lines', linesClass: 'line' });

// Wrap each line in a mask container

split.lines.forEach(line => {

const wrapper = document.createElement('div');

wrapper.style.overflow = 'hidden';

line.parentNode.insertBefore(wrapper, line);

wrapper.appendChild(line);

});

gsap.from(split.lines, {

yPercent: 100,

opacity: 0,

duration: 1,

stagger: 0.1,

ease: 'power4.out'

});

```

---

Debugging

```javascript

// Enable dev warnings

gsap.config({

nullTargetWarn: true

});

// ScrollTrigger markers (dev only)

ScrollTrigger.defaults({

markers: process.env.NODE_ENV === 'development'

});

// Log animation state

gsap.to('.el', {

x: 100,

onUpdate: function() {

console.log('Progress:', this.progress());

}

});

```

---

Framework Integration

See [framework-integration.md](references/framework-integration.md) for:

  • React with @gsap/react
  • Vue composition API patterns
  • Svelte lifecycle patterns
  • Vanilla JS module patterns

---

Resources

  • [GSAP Docs](https://gsap.com/docs/v3/)
  • [GSAP Eases Visualizer](https://gsap.com/docs/v3/Eases/)
  • [ScrollTrigger Demos](https://gsap.com/scroll/)
  • [GreenSock Forums](https://gsap.com/community/)