GSAP guidance for code-driven web motion, including timelines, ScrollTrigger, SplitText, Flip, and smooth-scroll synchronization.
Real-world examples not captured yet
This skill shows a gallery of live HTML demos (CDN libraries welcome — GSAP, Three.js, etc.) rendered inline via srcdoc.
Skill markdown
# GSAP for the Web
GSAP (GreenSock Animation Platform) is the workhorse for code-driven web motion: sequenced timelines, scroll-driven storytelling, text reveals, and layout transitions. As of GSAP 3.12+, every plugin (ScrollTrigger, SplitText, Flip, MotionPath, MorphSVG, Draggable, Observer) is 100% free, including for commercial use.
## When to use
- Scroll-driven storytelling: pinned sections, parallax, progress scrubbing, horizontal scroll
- Sequenced hero animations and complex multi-element timelines with precise overlap control
- Text reveals split into chars/words/lines (SplitText)
- Layout transitions where an element changes position/size/parent (Flip)
- Any motion needing fine timing control, easing precision, or imperative orchestration
## Install and register
```js
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { SplitText } from "gsap/SplitText";
import { Flip } from "gsap/Flip";
gsap.registerPlugin(ScrollTrigger, SplitText, Flip);
```
Plugins MUST be registered before use or they silently no-op. With a bundler, register once at app entry.
## Core techniques
### Timelines first
Prefer one timeline over many independent tweens — it gives a single playhead, relative positioning, and easy reversal.
```js
const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
tl.from(".title", { yPercent: 100, opacity: 0 })
.from(".sub", { y: 20, opacity: 0 }, "-=0.3") // start 0.3s before prev ends
.from(".cta", { scale: 0.9, opacity: 0 }, "<"); // align to prev tween START
```
Position parameter cheat sheet:
- `"+=0.5"` / `"-=0.3"` — relative to the end of the timeline (gap / overlap)
- `"<"` — start of the previous tween; `">"` — end of the previous tween
- `"<0.2"` — 0.2s after the previous tween's start
- `"myLabel"` — at a named label added via `tl.addLabel("myLabel")`
Use `.from()` for entrances (animates FROM the given values TO current CSS), `.to()` for exits, `.fromTo()` when both ends must be explicit (most robust against re-runs).
### gsap.to vs set vs quickTo
```js
gsap.set(el, { autoAlpha: 0 }); // instant, no tween (autoAlpha = opacity + visibility)
const xTo = gsap.quickTo(el, "x", { duration: 0.4, ease: "power3" });
window.addEventListener("pointermove", (e) => xTo(e.clientX)); // fast repeated updates
```
`autoAlpha` is preferred over raw `opacity` because it also toggles `visibility:hidden` at 0, removing the element from hit-testing.
### ScrollTrigger basics
```js
gsap.to(".panel", {
xPercent: -100,
ease: "none",
scrollTrigger: {
trigger: ".wrap",
start: "top top", // when trigger top hits viewport top
end: "+=2000", // 2000px of scroll distance
pin: true, // freeze .wrap while the tween plays
scrub: 1, // tie progress to scrollbar (1 = 1s catch-up smoothing)
markers: true, // dev-only visual markers — remove for prod
},
});
```
Key semantics:
- `start`/`end` take `"triggerPos viewportPos"` (e.g. `"top center"`) or `"+=px"`.
- `scrub: true` locks animation progress to scroll exactly; `scrub: <number>` adds smoothing lag.
- `toggleActions: "play pause resume reverse"` controls onEnter/onLeave/onEnterBack/onLeaveBack for non-scrubbed triggers.
- Use `ease: "none"` for scrubbed tweens so motion tracks scroll linearly.
### Smooth scroll (Lenis) + ScrollTrigger
Pairing Lenis (or Locomotive) smooth scrolling with ScrollTrigger desyncs unless both run on one loop. Lenis smooths scroll on its own rAF while ScrollTrigger reads scroll on GSAP's ticker; when they tick independently ScrollTrigger samples a stale position. The fix: drive Lenis from GSAP's ticker and update ScrollTrigger on every Lenis scroll.
```js
import Lenis from "lenis";
const lenis = new Lenis({ duration: 1.2, smoothWheel: true });
lenis.on("scroll", ScrollTrigger.update); // 1. update ScrollTrigger on every Lenis scroll
gsap.ticker.add((t) => lenis.raf(t * 1000)); // 2. one loop: ticker drives Lenis (seconds → ms)
gsap.ticker.lagSmoothing(0); // 3. stop GSAP catch-up jitter on heavy frames
```
Critical: `gsap.ticker` passes time in **seconds**, `lenis.raf()` wants **milliseconds** — multiply by 1000. Do NOT also run a standalone `requestAnimationFrame(raf)` loop for Lenis; that double-drives it.
Common bugs:
- **Jitter/stutter** — a leftover `requestAnimationFrame(raf)` loop competing with the ticker, or missing `lagSmoothing(0)`. Remove the rogue loop; set lag smoothing to 0.
- **Markers drift** from their triggers — `ScrollTrigger.update` is not subscribed to `lenis.on("scroll", …)`.
- **Pins break** — under Lenis do NOT set a `scrollerProxy` (it scrolls the document). Under Locomotive you MUST wire `scrollerProxy` + `pinType` and set `scroller:` on every trigger.
- **Scroll stuck / flipped direction** — missing the `* 1000` unit conversion, or two loops out of order.
Cleanup on SPA unmount: `gsap.ticker.remove(up
…More from iart-ai
- 60fps AnimationWeb animation performance guidance for avoiding layout thrashing and reaching smooth 60/120fps motion with compositor-friendly techniques.
- Accessible AnimationTiered reduced-motion patterns for CSS, GSAP, Framer Motion, Lenis, and other web animation systems.
- Ascii AnimationThis skill should be used when the user asks to "make an ASCII animation", "build a terminal/CLI intro or loader", "convert an image or video to ASCII art", "add an ASCII shader/post-effect to a canvas or Three.js scene", "create retro/hacker text-character motion", or "animate text characters with a brightness ramp". Covers generative ASCII fields, image/video/3D-to-ASCII, and animated character art for both web and terminal.
- GlassmorphismThis skill should be used when the user asks to "add a glassmorphism effect", "frosted glass UI", "Apple liquid glass style", "frosted blur card", "translucent glass panel animation", "make a frosted nav bar", "build a glass modal/dialog", "animate a glass card on hover", or "add a refracting liquid-glass hero". Covers frosted translucent panels with backdrop-filter blur, edge/specular highlights, SVG liquid-glass refraction, motion on hover/scroll/enter, and accessible reduced-transparency fallbacks.
- Lottie AnimationLottie and dotLottie integration guidance for playback control, interactivity, runtime theming, and cross-platform export workflows.
- Micro InteractionUI motion guidance for hover and press feedback, toggles, toasts, drawers, modals, list transitions, and shared-element interactions.