|
| 1 | +--- |
| 2 | +name: gsap-framer-scroll-animation |
| 3 | +description: >- |
| 4 | + Use this skill whenever the user wants to build scroll animations, scroll effects, |
| 5 | + parallax, scroll-triggered reveals, pinned sections, horizontal scroll, text animations, |
| 6 | + or any motion tied to scroll position — in vanilla JS, React, or Next.js. |
| 7 | + Covers GSAP ScrollTrigger (pinning, scrubbing, snapping, timelines, horizontal scroll, |
| 8 | + ScrollSmoother, matchMedia) and Framer Motion / Motion v12 (useScroll, useTransform, |
| 9 | + useSpring, whileInView, variants). Use this skill even if the user just says |
| 10 | + "animate on scroll", "fade in as I scroll", "make it scroll like Apple", |
| 11 | + "parallax effect", "sticky section", "scroll progress bar", or "entrance animation". |
| 12 | + Also triggers for Copilot prompt patterns for GSAP or Framer Motion code generation. |
| 13 | + Pairs with the premium-frontend-ui skill for creative philosophy and design-level polish. |
| 14 | +--- |
| 15 | + |
| 16 | +# GSAP & Framer Motion — Scroll Animations Skill |
| 17 | + |
| 18 | +Production-grade scroll animations with GitHub Copilot prompts, ready-to-use code recipes, and deep API references. |
| 19 | + |
| 20 | +> **Design Companion:** This skill provides the *technical implementation* for scroll-driven motion. |
| 21 | +> For the *creative philosophy*, design principles, and premium aesthetics that should guide **how** |
| 22 | +> and **when** to animate, always cross-reference the **premium-frontend-ui** skill. |
| 23 | +> Together they form a complete approach: premium-frontend-ui decides the **what** and **why**; |
| 24 | +> this skill delivers the **how**. |
| 25 | +
|
| 26 | +## Quick Library Selector |
| 27 | + |
| 28 | +| Need | Use | |
| 29 | +|---|---| |
| 30 | +| Vanilla JS, Webflow, Vue | **GSAP** | |
| 31 | +| Pinning, horizontal scroll, complex timelines | **GSAP** | |
| 32 | +| React / Next.js, declarative style | **Framer Motion** | |
| 33 | +| whileInView entrance animations | **Framer Motion** | |
| 34 | +| Both in same Next.js app | See notes in references | |
| 35 | + |
| 36 | +Read the relevant reference file for full recipes and Copilot prompts: |
| 37 | + |
| 38 | +- **GSAP** → `references/gsap.md` — ScrollTrigger API, all recipes, React integration |
| 39 | +- **Framer Motion** → `references/framer.md` — useScroll, useTransform, all recipes |
| 40 | + |
| 41 | +## Setup (Always Do First) |
| 42 | + |
| 43 | +### GSAP |
| 44 | +```bash |
| 45 | +npm install gsap |
| 46 | +``` |
| 47 | +```js |
| 48 | +import gsap from 'gsap'; |
| 49 | +import { ScrollTrigger } from 'gsap/ScrollTrigger'; |
| 50 | +gsap.registerPlugin(ScrollTrigger); // MUST call before any ScrollTrigger usage |
| 51 | +``` |
| 52 | + |
| 53 | +### Framer Motion (Motion v12, 2025) |
| 54 | +```bash |
| 55 | +npm install motion # new package name since mid-2025 |
| 56 | +# or: npm install framer-motion — still works, same API |
| 57 | +``` |
| 58 | +```js |
| 59 | +import { motion, useScroll, useTransform, useSpring } from 'motion/react'; |
| 60 | +// legacy: import { motion } from 'framer-motion' — also valid |
| 61 | +``` |
| 62 | + |
| 63 | +## Workflow |
| 64 | + |
| 65 | +1. Interpret the user's intent to identify if GSAP or Framer Motion is the best fit. |
| 66 | +2. Read the relevant reference document in `references/` for detailed APIs and patterns. |
| 67 | +3. Suggest the required package installation if not already present. |
| 68 | +4. Implement the scaffold for the animation structure, adhering to the requested format (React components, hook requirements, or vanilla JS). |
| 69 | +5. Apply the correct tools (scrolling vs in-view elements) ensuring accessibility options are present and hooks don't cause infinite re-renders. |
| 70 | + |
| 71 | +## The 5 Most Common Scroll Patterns |
| 72 | + |
| 73 | +Quick reference — full recipes with Copilot prompts are in the reference files. |
| 74 | + |
| 75 | +### 1. Fade-in on enter (GSAP) |
| 76 | +```js |
| 77 | +gsap.from('.card', { |
| 78 | + opacity: 0, y: 50, stagger: 0.15, duration: 0.8, |
| 79 | + scrollTrigger: { trigger: '.card', start: 'top 85%' } |
| 80 | +}); |
| 81 | +``` |
| 82 | + |
| 83 | +### 2. Fade-in on enter (Framer Motion) |
| 84 | +```jsx |
| 85 | +<motion.div |
| 86 | + initial={{ opacity: 0, y: 40 }} |
| 87 | + whileInView={{ opacity: 1, y: 0 }} |
| 88 | + viewport={{ once: true, margin: '-80px' }} |
| 89 | + transition={{ duration: 0.6 }} |
| 90 | +/> |
| 91 | +``` |
| 92 | + |
| 93 | +### 3. Scrub / scroll-linked (GSAP) |
| 94 | +```js |
| 95 | +gsap.to('.hero-img', { |
| 96 | + scale: 1.3, opacity: 0, ease: 'none', |
| 97 | + scrollTrigger: { trigger: '.hero', start: 'top top', end: 'bottom top', scrub: true } |
| 98 | +}); |
| 99 | +``` |
| 100 | + |
| 101 | +### 4. Scroll-linked (Framer Motion) |
| 102 | +```jsx |
| 103 | +const { scrollYProgress } = useScroll({ target: ref, offset: ['start end', 'end start'] }); |
| 104 | +const y = useTransform(scrollYProgress, [0, 1], [0, -100]); |
| 105 | +return <motion.div style={{ y }} />; |
| 106 | +``` |
| 107 | + |
| 108 | +### 5. Pinned timeline (GSAP) |
| 109 | +```js |
| 110 | +const tl = gsap.timeline({ |
| 111 | + scrollTrigger: { trigger: '.section', pin: true, scrub: 1, start: 'top top', end: '+=200%' } |
| 112 | +}); |
| 113 | +tl.from('.title', { opacity: 0, y: 60 }).from('.img', { scale: 0.85 }); |
| 114 | +``` |
| 115 | + |
| 116 | +## Critical Rules (Apply Always) |
| 117 | + |
| 118 | +- **GSAP**: always call `gsap.registerPlugin(ScrollTrigger)` before using it |
| 119 | +- **GSAP scrub**: always use `ease: 'none'` — easing feels wrong when scrub is active |
| 120 | +- **GSAP React**: use `useGSAP` from `@gsap/react`, never plain `useEffect` — it auto-cleans ScrollTriggers |
| 121 | +- **GSAP debug**: add `markers: true` during development; remove before production |
| 122 | +- **Framer**: `useTransform` output must go into `style` prop of a `motion.*` element, not a plain div |
| 123 | +- **Framer Next.js**: always add `'use client'` at top of any file using motion hooks |
| 124 | +- **Both**: animate only `transform` and `opacity` — avoid `width`, `height`, `box-shadow` |
| 125 | +- **Accessibility**: always check `prefers-reduced-motion` — see each reference file for patterns |
| 126 | +- **Premium polish**: follow the **premium-frontend-ui** skill principles for motion timing, easing curves, and restraint — animation should enhance, never overwhelm |
| 127 | + |
| 128 | +## Copilot Prompting Tips |
| 129 | + |
| 130 | +- Give Copilot the full selector, base image, and scroll range upfront — vague prompts produce vague code |
| 131 | +- For GSAP, always specify: selector, start/end strings, whether you want scrub or toggleActions |
| 132 | +- For Framer, always specify: which hook (useScroll vs whileInView), offset values, what to transform |
| 133 | +- Paste the exact error message when asking `/fix` — Copilot fixes are dramatically better with real errors |
| 134 | +- Use `@workspace` scope in Copilot Chat so it reads your existing component structure |
| 135 | + |
| 136 | +## Reference Files |
| 137 | + |
| 138 | +| File | Contents | |
| 139 | +|---|---| |
| 140 | +| `references/gsap.md` | Full ScrollTrigger API reference, 10 recipes, React (useGSAP), Lenis, matchMedia, accessibility | |
| 141 | +| `references/framer.md` | Full useScroll / useTransform API, 8 recipes, variants, Motion v12 notes, Next.js tips | |
| 142 | + |
| 143 | +## Related Skills |
| 144 | + |
| 145 | +| Skill | Relationship | |
| 146 | +|---|---| |
| 147 | +| **premium-frontend-ui** | Creative philosophy, design principles, and aesthetic guidelines — defines *when* and *why* to animate | |
0 commit comments