mirror of
https://github.com/greensock/gsap-skills
synced 2026-09-22 23:34:24 +08:00
Added examples, llms.txt, and frameworks
This commit is contained in:
@@ -51,6 +51,46 @@ Clone this repo and copy the skill folders into the appropriate directory for yo
|
||||
| **gsap-utils** | gsap.utils: clamp, mapRange, normalize, interpolate, random, snap, toArray, selector, wrap, pipe, and other helpers |
|
||||
| **gsap-react** | React: useGSAP hook, refs, `gsap.context()`, cleanup, SSR |
|
||||
| **gsap-performance** | Performance: transforms over layout props, will-change, batching, ScrollTrigger tips |
|
||||
| **gsap-frameworks** | Vue, Svelte, etc.: lifecycle, scoping selectors, cleanup on unmount |
|
||||
|
||||
## Quick reference — Canonical snippet for AI agents
|
||||
|
||||
When suggesting or generating GSAP code, use this pattern as the shared starting point:
|
||||
|
||||
```javascript
|
||||
// 1. Imports and plugin registration (once per app)
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
|
||||
// 2. Single tween — prefer transform aliases and autoAlpha
|
||||
gsap.to(".box", { x: 100, autoAlpha: 1, duration: 0.6, ease: "power2.inOut" });
|
||||
|
||||
// 3. Timeline for sequencing (prefer over chained delay)
|
||||
const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2" } });
|
||||
tl.to(".a", { x: 100 })
|
||||
.to(".b", { y: 50 }, "+=0.2")
|
||||
.to(".c", { opacity: 0 }, "-=0.1");
|
||||
|
||||
// 4. ScrollTrigger — attach to timeline or top-level tween; call refresh after layout changes
|
||||
const tl2 = gsap.timeline({
|
||||
scrollTrigger: {
|
||||
trigger: ".section",
|
||||
start: "top center",
|
||||
end: "bottom center",
|
||||
scrub: true
|
||||
}
|
||||
});
|
||||
tl2.to(".panel", { x: 100 })
|
||||
.to(".panel", { rotation: 5, duration: 0.7 });
|
||||
// After DOM/layout changes: ScrollTrigger.refresh();
|
||||
|
||||
// 5. React: useGSAP + scope + cleanup (no selector without scope)
|
||||
// import { useGSAP } from "@gsap/react";
|
||||
// gsap.registerPlugin(useGSAP);
|
||||
// useGSAP(() => { gsap.to(ref.current, { x: 100 }); }, { scope: containerRef });
|
||||
// Or: useEffect(() => { const ctx = gsap.context(() => { ... }, containerRef); return () => ctx.revert(); }, []);
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
@@ -67,6 +107,7 @@ gsap-skills/
|
||||
.cursor-plugin/ # Cursor plugin config (plugin.json, marketplace.json)
|
||||
assets/ # Logo and icon assets (e.g. gsap-green.svg, gsap-icon-square.svg)
|
||||
skills/
|
||||
llms.txt # Skill index for agents (names, summaries, trigger terms)
|
||||
gsap-core/ SKILL.md
|
||||
gsap-timeline/ SKILL.md
|
||||
gsap-scrolltrigger/ SKILL.md
|
||||
@@ -74,6 +115,8 @@ gsap-skills/
|
||||
gsap-utils/ SKILL.md
|
||||
gsap-react/ SKILL.md
|
||||
gsap-performance/ SKILL.md
|
||||
gsap-frameworks/ SKILL.md
|
||||
examples/ # Minimal reference demos (vanilla + React)
|
||||
```
|
||||
|
||||
## GitHub Copilot
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# GSAP skills — reference examples
|
||||
|
||||
Minimal demos that follow the skills exactly: transforms, autoAlpha, timelines, ScrollTrigger, and (in React) useGSAP with scope and cleanup.
|
||||
|
||||
## Vanilla (HTML + JS)
|
||||
|
||||
- **examples/vanilla/** — single HTML page + ES module.
|
||||
- Uses GSAP from CDN (ESM). Open with a local server that supports ES modules (e.g. `npx serve examples/vanilla` from repo root).
|
||||
- Patterns: `gsap.to()` with `x`/`autoAlpha`, `gsap.timeline()` with defaults and position parameter, ScrollTrigger on the timeline.
|
||||
|
||||
## React
|
||||
|
||||
- **examples/react/** — Vite + React + `@gsap/react`.
|
||||
- From repo root: `cd examples/react && npm install && npm run dev`.
|
||||
- Patterns: `useGSAP()` with `scope: containerRef`, refs for targets, no selectors without scope; cleanup is automatic on unmount.
|
||||
|
||||
These examples are intended as reference implementations for AI agents and for quick manual verification of the skill patterns.
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Minimal GSAP React example — follows gsap-react skill: useGSAP, scope, cleanup.
|
||||
* No selector without scope; refs for targets; automatic revert on unmount.
|
||||
*/
|
||||
import { useRef } from "react";
|
||||
import { useGSAP } from "@gsap/react";
|
||||
import { gsap } from "gsap";
|
||||
|
||||
// Register useGSAP once (could be in main.jsx for app-level)
|
||||
gsap.registerPlugin(useGSAP);
|
||||
|
||||
function App() {
|
||||
const containerRef = useRef(null);
|
||||
const boxRef = useRef(null);
|
||||
|
||||
useGSAP(
|
||||
() => {
|
||||
// Scoped to containerRef — selectors only match inside container
|
||||
gsap.to(boxRef.current, { x: 100, duration: 0.6, ease: "power2" });
|
||||
gsap.from(".item", { autoAlpha: 0, y: 20, stagger: 0.1 });
|
||||
},
|
||||
{ scope: containerRef }
|
||||
);
|
||||
|
||||
return (
|
||||
<div ref={containerRef} style={{ padding: "2rem" }}>
|
||||
<h1>GSAP React — useGSAP + scope + cleanup</h1>
|
||||
<div
|
||||
ref={boxRef}
|
||||
className="box"
|
||||
style={{
|
||||
width: 80,
|
||||
height: 80,
|
||||
background: "#0fa",
|
||||
borderRadius: 8,
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
/>
|
||||
<div className="item" style={{ margin: "0.5rem 0" }}>Item 1</div>
|
||||
<div className="item" style={{ margin: "0.5rem 0" }}>Item 2</div>
|
||||
<div className="item" style={{ margin: "0.5rem 0" }}>Item 3</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>GSAP React — useGSAP + scope + cleanup</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "gsap-skills-example-react",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@gsap/react": "^2.1.2",
|
||||
"gsap": "^3.14.2",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"vite": "^5.4.10"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
root: ".",
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>GSAP vanilla — canonical patterns</title>
|
||||
<style>
|
||||
body { font-family: system-ui, sans-serif; padding: 2rem; }
|
||||
.box { width: 80px; height: 80px; background: #0fa; border-radius: 8px; margin: 1rem 0; }
|
||||
.item { margin: 0.5rem 0; opacity: 0; }
|
||||
.section { min-height: 120vh; padding: 2rem 0; }
|
||||
.panel { width: 100px; height: 60px; background: #9cf; border-radius: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>GSAP vanilla — transforms, autoAlpha, timeline, ScrollTrigger</h1>
|
||||
|
||||
<h2>1. Single tween (transform + autoAlpha)</h2>
|
||||
<div class="box" id="single" style="opacity: 0;"></div>
|
||||
|
||||
<h2>2. Timeline (sequencing)</h2>
|
||||
<div class="box a">A</div>
|
||||
<div class="box b">B</div>
|
||||
<div class="box c">C</div>
|
||||
|
||||
<h2>3. ScrollTrigger (timeline + scrub)</h2>
|
||||
<section class="section" id="scroll-section">
|
||||
<div class="panel">Panel</div>
|
||||
</section>
|
||||
|
||||
<script type="module" src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Minimal GSAP vanilla example — follows skills: transforms, autoAlpha, timeline, ScrollTrigger.
|
||||
* Run from repo root: npx serve examples/vanilla (or open index.html with a local server that supports ES modules).
|
||||
*/
|
||||
import { gsap } from "https://cdn.jsdelivr.net/npm/gsap@3.14.2/index.js";
|
||||
import { ScrollTrigger } from "https://cdn.jsdelivr.net/npm/gsap@3.14.2/ScrollTrigger.js";
|
||||
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
|
||||
// 1. Single tween — transform alias x, autoAlpha
|
||||
gsap.to("#single", {
|
||||
x: 120,
|
||||
autoAlpha: 1,
|
||||
duration: 0.6,
|
||||
ease: "power2"
|
||||
});
|
||||
|
||||
// 2. Timeline for sequencing (defaults, position parameter)
|
||||
const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2" } });
|
||||
tl.to(".a", { x: 100 })
|
||||
.to(".b", { y: 40 }, "+=0.2")
|
||||
.to(".c", { autoAlpha: 0 }, "-=0.1");
|
||||
|
||||
// 3. ScrollTrigger on timeline (not on child tween)
|
||||
const tl2 = gsap.timeline({
|
||||
scrollTrigger: {
|
||||
trigger: "#scroll-section",
|
||||
start: "top center",
|
||||
end: "bottom center",
|
||||
scrub: true
|
||||
}
|
||||
});
|
||||
tl2.to(".panel", { x: 100 })
|
||||
.to(".panel", { rotation: 5, duration: 0.7 });
|
||||
|
||||
// After dynamic layout changes you would call: ScrollTrigger.refresh();
|
||||
@@ -10,6 +10,8 @@ license: MIT
|
||||
|
||||
Apply when writing or reviewing GSAP animations that use the core engine: single tweens, eases, staggers, or when explaining how GSAP tweens work.
|
||||
|
||||
**Related skills:** For sequencing multiple steps use **gsap-timeline**; for scroll-linked animation use **gsap-scrolltrigger**; for React use **gsap-react**; for plugins (Flip, Draggable, etc.) use **gsap-plugins**; for helpers (clamp, mapRange, etc.) use **gsap-utils**; for performance use **gsap-performance**.
|
||||
|
||||
**Context:** GSAP was acquired by Webflow and powers **Webflow Interactions**. Code generated or run by Webflow’s interaction system is GSAP-based; when users ask about Webflow animations or interactions not behaving as expected, GSAP docs and patterns (e.g. tweens, ScrollTrigger) are relevant for debugging or customizing.
|
||||
|
||||
## When to Use GSAP
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
name: gsap-frameworks
|
||||
description: Use GSAP correctly in Vue, Svelte, and other non-React frameworks — lifecycle (when to create/kill tweens and ScrollTriggers), scoping selectors, cleanup on unmount. Use when animating in Vue, Nuxt, Svelte, SvelteKit, or when the user asks about GSAP with Vue, Svelte, onMounted, onUnmounted, onMount, onDestroy.
|
||||
license: MIT
|
||||
---
|
||||
|
||||
# GSAP with Vue, Svelte, and Other Frameworks
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Apply when writing or reviewing GSAP code in Vue (or Nuxt), Svelte (or SvelteKit), or other component frameworks that use a lifecycle (mounted/unmounted). For **React** specifically, use **gsap-react** (useGSAP hook, gsap.context()).
|
||||
|
||||
**Related skills:** For tweens and timelines use **gsap-core** and **gsap-timeline**; for scroll-based animation use **gsap-scrolltrigger**; for React use **gsap-react**.
|
||||
|
||||
## Principles (All Frameworks)
|
||||
|
||||
- **Create** tweens and ScrollTriggers **after** the component’s DOM is available (e.g. onMounted, onMount).
|
||||
- **Kill or revert** them in the **unmount** (or equivalent) cleanup so nothing runs on detached nodes and there are no leaks.
|
||||
- **Scope selectors** to the component root so `.box` and similar only match elements inside that component, not the rest of the page.
|
||||
|
||||
## Vue 3 (Composition API)
|
||||
|
||||
Use **onMounted** to run GSAP after the component is in the DOM. Use **onUnmounted** to clean up.
|
||||
|
||||
```javascript
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
||||
gsap.registerPlugin(ScrollTrigger); // once per app, e.g. in main.js
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const container = ref(null);
|
||||
let ctx;
|
||||
|
||||
onMounted(() => {
|
||||
if (!container.value) return;
|
||||
ctx = gsap.context(() => {
|
||||
gsap.to(".box", { x: 100, duration: 0.6 });
|
||||
gsap.from(".item", { autoAlpha: 0, y: 20, stagger: 0.1 });
|
||||
}, container.value);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
ctx?.revert();
|
||||
});
|
||||
|
||||
return { container };
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
- ✅ **gsap.context(scope)** — pass the container ref (e.g. `container.value`) as the second argument so selectors like `.item` are scoped to that root. All animations and ScrollTriggers created inside the callback are tracked and reverted when **ctx.revert()** is called.
|
||||
- ✅ **onUnmounted** — always call **ctx.revert()** so tweens and ScrollTriggers are killed and inline styles reverted.
|
||||
|
||||
## Vue 3 (script setup)
|
||||
|
||||
Same idea with `<script setup>` and refs:
|
||||
|
||||
```javascript
|
||||
<script setup>
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
||||
|
||||
const container = ref(null);
|
||||
let ctx;
|
||||
|
||||
onMounted(() => {
|
||||
if (!container.value) return;
|
||||
ctx = gsap.context(() => {
|
||||
gsap.to(".box", { x: 100 });
|
||||
gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
|
||||
}, container.value);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
ctx?.revert();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="container">
|
||||
<div class="box">Box</div>
|
||||
<div class="item">Item</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Svelte
|
||||
|
||||
Use **onMount** to run GSAP after the DOM is ready. Use the **returned cleanup function** from onMount (or track the context and clean up in a reactive block / component destroy) to revert. Svelte 5 uses a different lifecycle; the same principle applies: create in “mounted” and revert in “destroyed.”
|
||||
|
||||
```javascript
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
||||
|
||||
let container;
|
||||
|
||||
onMount(() => {
|
||||
if (!container) return;
|
||||
const ctx = gsap.context(() => {
|
||||
gsap.to(".box", { x: 100 });
|
||||
gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
|
||||
}, container);
|
||||
return () => ctx.revert();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div bind:this={container}>
|
||||
<div class="box">Box</div>
|
||||
<div class="item">Item</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
- ✅ **bind:this={container}** — get a reference to the root element so you can pass it to **gsap.context(scope)**.
|
||||
- ✅ **return () => ctx.revert()** — Svelte’s onMount can return a cleanup function; call **ctx.revert()** there so cleanup runs when the component is destroyed.
|
||||
|
||||
## Scoping Selectors
|
||||
|
||||
Do not use global selectors that can match elements outside the current component. Always pass the **scope** (container element or ref) as the second argument to **gsap.context(callback, scope)** so that any selector run inside the callback is limited to that subtree.
|
||||
|
||||
- ✅ **gsap.context(() => { gsap.to(".box", ...) }, containerRef)** — `.box` is only searched inside `containerRef`.
|
||||
- ❌ Running **gsap.to(".box", ...)** without a context scope in a component can affect other instances or the rest of the page.
|
||||
|
||||
## ScrollTrigger Cleanup
|
||||
|
||||
ScrollTrigger instances are created when you use the `scrollTrigger` config on a tween/timeline or **ScrollTrigger.create()**. They are **included** in **gsap.context()** and reverted when you call **ctx.revert()**. So:
|
||||
|
||||
- Create ScrollTriggers inside the same **gsap.context()** callback you use for tweens.
|
||||
- Call **ScrollTrigger.refresh()** after layout changes (e.g. after data loads) that affect trigger positions; in Vue/Svelte that often means after the DOM updates (e.g. nextTick in Vue, tick in Svelte, or after async content load).
|
||||
|
||||
## When to Create vs Kill
|
||||
|
||||
| Lifecycle | Action |
|
||||
|-----------------|--------|
|
||||
| **Mounted** | Create tweens and ScrollTriggers inside **gsap.context(scope)**. |
|
||||
| **Unmount / Destroy** | Call **ctx.revert()** so all animations and ScrollTriggers in that context are killed and inline styles reverted. |
|
||||
|
||||
Do not create GSAP animations in the component’s setup or in a synchronous top-level script that runs before the root element exists. Wait for **onMounted** / **onMount** (or equivalent) so the container ref is in the DOM.
|
||||
|
||||
## Do Not
|
||||
|
||||
- ❌ Create tweens or ScrollTriggers before the component is mounted (e.g. in setup without onMounted); the DOM nodes may not exist yet.
|
||||
- ❌ Use selector strings without a **scope** (pass the container to gsap.context() as the second argument) so selectors don’t match elements outside the component.
|
||||
- ❌ Skip cleanup; always call **ctx.revert()** in onUnmounted / onMount’s return so animations and ScrollTriggers are killed when the component is destroyed.
|
||||
- ❌ Register plugins inside a component body that runs every render (it doesn't hurt anything, it's just wasteful); register once at app level.
|
||||
|
||||
### Learn More
|
||||
|
||||
- **gsap-react** skill for React-specific patterns (useGSAP, contextSafe).
|
||||
@@ -10,6 +10,8 @@ license: MIT
|
||||
|
||||
Apply when optimizing GSAP animations for smooth 60fps, reducing layout/paint cost, or when the user asks about performance, jank, or best practices for fast animations.
|
||||
|
||||
**Related skills:** Build animations with **gsap-core** (transforms, autoAlpha) and **gsap-timeline**; for ScrollTrigger performance see **gsap-scrolltrigger**.
|
||||
|
||||
## Prefer Transform and Opacity
|
||||
|
||||
Animating **transform** (`x`, `y`, `scaleX`, `scaleY`, `rotation`, `rotationX`, `rotationY`, `skewX`, `skewY`) and **opacity** keeps work on the compositor and avoids layout and most paint. Avoid animating layout-heavy properties when a transform can achieve the same effect.
|
||||
|
||||
@@ -10,6 +10,8 @@ license: MIT
|
||||
|
||||
Apply when using or reviewing code that uses GSAP plugins: registering plugins, scroll-to, flip/FLIP animations, draggable elements, SVG (DrawSVG, MorphSVG, MotionPath), text (SplitText, ScrambleText), physics, easing plugins (CustomEase, EasePack, CustomWiggle, CustomBounce), or GSDevTools. ScrollTrigger has its own skill (gsap-scrolltrigger).
|
||||
|
||||
**Related skills:** For core tweens use **gsap-core**; for ScrollTrigger use **gsap-scrolltrigger**; for React use **gsap-react**.
|
||||
|
||||
## Registering Plugins
|
||||
|
||||
Register each plugin once so GSAP (and bundlers) know to include it. Use **gsap.registerPlugin()** with every plugin used in the project:
|
||||
|
||||
@@ -10,6 +10,7 @@ license: MIT
|
||||
|
||||
Apply when writing or reviewing GSAP code in React (or React-based frameworks like Next.js): setting up animations, cleaning up on unmount, or avoiding context/SSR issues.
|
||||
|
||||
**Related skills:** For tweens and timelines use **gsap-core** and **gsap-timeline**; for scroll-based animation use **gsap-scrolltrigger**; for Vue/Svelte or other frameworks use **gsap-frameworks**.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -124,6 +125,7 @@ GSAP runs in the browser. Do not call gsap or ScrollTrigger during SSR.
|
||||
|
||||
## Do Not
|
||||
|
||||
- ❌ Target by **selector without a scope**; always pass **scope** (ref or element) in useGSAP or gsap.context() so selectors like `.box` are limited to that root and do not match elements outside the component.
|
||||
- ❌ Animate using selector strings that can match elements outside the current component unless a `scope` is defined in useGSAP or gsap.context() so only elements inside the component are affected.
|
||||
- ❌ Skip cleanup; always revert context or kill tweens/ScrollTriggers in the effect return to avoid leaks and updates on unmounted nodes.
|
||||
- ❌ Run GSAP or ScrollTrigger during SSR; keep all usage inside client-only lifecycle (e.g. useGSAP).
|
||||
|
||||
@@ -10,6 +10,8 @@ license: MIT
|
||||
|
||||
Apply when implementing scroll-driven animations: triggering tweens/timelines on scroll, pinning elements, scrubbing animation to scroll position, or when the user mentions ScrollTrigger, scroll animations, or pinning.
|
||||
|
||||
**Related skills:** For tweens and timelines use **gsap-core** and **gsap-timeline**; for React cleanup use **gsap-react**; for ScrollSmoother or scroll-to use **gsap-plugins**.
|
||||
|
||||
## Registering the Plugin
|
||||
|
||||
ScrollTrigger is a plugin. After loading the script, register it once:
|
||||
@@ -278,7 +280,9 @@ In React, use the `useGSAP()` hook (@gsap/react NPM package) to ensure proper cl
|
||||
|
||||
## Do Not
|
||||
|
||||
- ❌ Nest ScrollTriggered animations inside of a parent timeline. ScrollTriggers should only exist on top-level animations. Wrong: `gsap.timeline().to(..., {scrollTrigger: {...}})`. Correct: `gsap.timeline({scrollTrigger: {...}}).to(...)` (the tween inside the timeline shouldn't have a ScrollTrigger).
|
||||
- ❌ Put ScrollTrigger on a **child tween** when it's part of a timeline; put it on the **timeline** or a **top-level tween** only. Wrong: `gsap.timeline().to(".a", { scrollTrigger: {...} })`. Correct: `gsap.timeline({ scrollTrigger: {...} }).to(".a", { x: 100 })`.
|
||||
- ❌ Forget to call **ScrollTrigger.refresh()** after DOM/layout changes (new content, images, fonts) that affect trigger positions; viewport resize is auto-handled, but dynamic content is not.
|
||||
- ❌ Nest ScrollTriggered animations inside of a parent timeline. ScrollTriggers should only exist on top-level animations.
|
||||
- ❌ Forget to **gsap.registerPlugin(ScrollTrigger)** before using ScrollTrigger.
|
||||
- ❌ Use **scrub** and **toggleActions** together on the same ScrollTrigger; choose one behavior. If both exist, **scrub** wins.
|
||||
- ❌ Use an ease other than **"none"** on the horizontal animation when using **containerAnimation** for fake horizontal scroll; it breaks the 1:1 scroll-to-position mapping.
|
||||
|
||||
@@ -10,6 +10,8 @@ license: MIT
|
||||
|
||||
Apply when building multi-step animations, coordinating several tweens in sequence or parallel, or when the user asks about timelines, sequencing, or keyframe-style animation in GSAP.
|
||||
|
||||
**Related skills:** For single tweens and eases use **gsap-core**; for scroll-driven timelines use **gsap-scrolltrigger**; for React use **gsap-react**.
|
||||
|
||||
## Creating a Timeline
|
||||
|
||||
```javascript
|
||||
@@ -99,5 +101,7 @@ master.to(".c", { opacity: 0 }, "+=0.2");
|
||||
|
||||
## Do Not
|
||||
|
||||
- ❌ Chain animations with **delay** when a **timeline** can sequence them; prefer `gsap.timeline()` and the position parameter for multi-step animation.
|
||||
- ❌ Forget to pass **defaults** (e.g. `defaults: { duration: 0.5, ease: "power2.out" }`) when many child tweens share the same duration or ease.
|
||||
- ❌ Forget that **duration** on the timeline constructor is not the same as tween duration; timeline “duration” is determined by its children.
|
||||
- ❌ Nest animations that contain a ScrollTrigger; ScrollTriggers should only be on top-level Tweens/Timelines.
|
||||
|
||||
@@ -10,6 +10,8 @@ license: MIT
|
||||
|
||||
Apply when writing or reviewing code that uses **gsap.utils** for math, array/collection handling, unit parsing, or value mapping in animations (e.g. mapping scroll to a value, randomizing, snapping to a grid, or normalizing inputs).
|
||||
|
||||
**Related skills:** Use with **gsap-core**, **gsap-timeline**, and **gsap-scrolltrigger** when building animations; CustomEase and other easing utilities are in **gsap-plugins**.
|
||||
|
||||
## Overview
|
||||
|
||||
**gsap.utils** provides pure helpers; no need to register. Use in tween vars (e.g. function-based values), in ScrollTrigger or Observer callbacks, or in any JS that drives GSAP. All are on **gsap.utils** (e.g. `gsap.utils.clamp()`).
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# GSAP Skills — Index for AI Agents
|
||||
|
||||
Use this file to discover which skill to load. Each skill lives in a directory of the same name under skills/ and contains SKILL.md.
|
||||
|
||||
## Skills
|
||||
|
||||
gsap-core
|
||||
Core API: gsap.to(), from(), fromTo(), easing, duration, stagger, defaults, transforms, autoAlpha.
|
||||
Triggers: GSAP tweens, easing, stagger, basic animation, Webflow interactions, transform, opacity.
|
||||
|
||||
gsap-timeline
|
||||
Timelines: gsap.timeline(), position parameter, labels, nesting, playback.
|
||||
Triggers: sequencing, timeline, keyframes, choreograph, multi-step animation, animation order.
|
||||
|
||||
gsap-scrolltrigger
|
||||
ScrollTrigger: scroll-linked animations, pinning, scrub, triggers, refresh, cleanup.
|
||||
Triggers: scroll animation, ScrollTrigger, pin, parallax, scroll-driven, scrub.
|
||||
|
||||
gsap-plugins
|
||||
Plugins: ScrollToPlugin, ScrollSmoother, Flip, Draggable, Inertia, Observer, SplitText, ScrambleText, SVG/physics, CustomEase, EasePack, GSDevTools.
|
||||
Triggers: plugin, scroll-to, flip, draggable, SVG drawing, MorphSVG, DrawSVG, MotionPath, SplitText, ScrambleText, CustomEase, registerPlugin.
|
||||
|
||||
gsap-utils
|
||||
gsap.utils: clamp, mapRange, normalize, interpolate, random, snap, toArray, wrap, pipe.
|
||||
Triggers: gsap.utils, clamp, mapRange, random, snap, toArray, wrap, interpolation.
|
||||
|
||||
gsap-react
|
||||
React: useGSAP hook, refs, gsap.context(), cleanup, SSR.
|
||||
Triggers: React, Next.js, useGSAP, cleanup on unmount, GSAP React.
|
||||
|
||||
gsap-performance
|
||||
Performance: transforms, will-change, batching, ScrollTrigger tips.
|
||||
Triggers: performance, 60fps, jank, animation performance, optimize.
|
||||
|
||||
gsap-frameworks
|
||||
Vue, Svelte, and other frameworks: lifecycle, when to create/kill tweens and ScrollTriggers, scoping selectors, cleanup on unmount.
|
||||
Triggers: Vue, Svelte, Nuxt, SvelteKit, framework, lifecycle, onMounted, onUnmounted.
|
||||
Reference in New Issue
Block a user