Production-grade scroll animations with GitHub Copilot prompts, ready-to-use code recipes, and deep API references.
Design Companion: This skill provides the technical implementation for scroll-driven motion. For the creative philosophy, design principles, and premium aesthetics that should guide how and when to animate, always cross-reference the premium-frontend-ui skill. Together they form a complete approach: premium-frontend-ui decides the what and why; this skill delivers the how.
| Need | Use |
|---|---|
| Vanilla JS, Webflow, Vue | GSAP |
| Pinning, horizontal scroll, complex timelines | GSAP |
| React / Next.js, declarative style | Framer Motion |
| whileInView entrance animations | Framer Motion |
| Both in same Next.js app | See notes in references |
Read the relevant reference file for full recipes and Copilot prompts:
references/gsap.md — ScrollTrigger API, all recipes, React integrationreferences/framer.md — useScroll, useTransform, all recipesnpm install gsap
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger); // MUST call before any ScrollTrigger usage
npm install motion # new package name since mid-2025
# or: npm install framer-motion — still works, same API
import { motion, useScroll, useTransform, useSpring } from 'motion/react';
// legacy: import { motion } from 'framer-motion' — also valid
references/ for detailed APIs and patterns.Quick reference — full recipes with Copilot prompts are in the reference files.
gsap.from('.card', {
opacity: 0, y: 50, stagger: 0.15, duration: 0.8,
scrollTrigger: { trigger: '.card', start: 'top 85%' }
});
<motion.div
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-80px' }}
transition={{ duration: 0.6 }}
/>
gsap.to('.hero-img', {
scale: 1.3, opacity: 0, ease: 'none',
scrollTrigger: { trigger: '.hero', start: 'top top', end: 'bottom top', scrub: true }
});
const { scrollYProgress } = useScroll({ target: ref, offset: ['start end', 'end start'] });
const y = useTransform(scrollYProgress, [0, 1], [0, -100]);
return <motion.div style={{ y }} />;
const tl = gsap.timeline({
scrollTrigger: { trigger: '.section', pin: true, scrub: 1, start: 'top top', end: '+=200%' }
});
tl.from('.title', { opacity: 0, y: 60 }).from('.img', { scale: 0.85 });
gsap.registerPlugin(ScrollTrigger) before using itease: 'none' — easing feels wrong when scrub is activeuseGSAP from @gsap/react, never plain useEffect — it auto-cleans ScrollTriggersmarkers: true during development; remove before productionuseTransform output must go into style prop of a motion.* element, not a plain div'use client' at top of any file using motion hookstransform and opacity — avoid width, height, box-shadow
prefers-reduced-motion — see each reference file for patterns/fix — Copilot fixes are dramatically better with real errors@workspace scope in Copilot Chat so it reads your existing component structure| File | Contents |
|---|---|
references/gsap.md |
Full ScrollTrigger API reference, 10 recipes, React (useGSAP), Lenis, matchMedia, accessibility |
references/framer.md |
Full useScroll / useTransform API, 8 recipes, variants, Motion v12 notes, Next.js tips |
| Skill | Relationship |
|---|---|
| premium-frontend-ui | Creative philosophy, design principles, and aesthetic guidelines — defines when and why to animate |