<< All versions
Skill v1.0.1
currentAutomated scan100/100bbeierle12/skill-mcp-claude/gsap-scrolltrigger
1 files
──Details
PublishedMay 14, 2026 at 07:41 PM
Content Hashsha256:c4a294c8c8b89b85...
Git SHAaf79a946e2f7
Bump Typepatch
──Files
Files (1 file, 9.8 KB)
SKILL.md9.8 KBactive
SKILL.md · 507 lines · 9.8 KB
version: "1.0.1" name: gsap-scrolltrigger description: Scroll-based animations using GSAP ScrollTrigger plugin including pinning, scrubbing, snap points, and parallax effects. Use when creating scroll-driven animations, sticky sections, progress indicators, or parallax scrolling experiences.
GSAP ScrollTrigger
Scroll-driven animations and interactions.
Quick Start
bash
npm install gsap
javascript
import gsap from 'gsap';import { ScrollTrigger } from 'gsap/ScrollTrigger';gsap.registerPlugin(ScrollTrigger);gsap.to('.box', {x: 500,scrollTrigger: {trigger: '.box',start: 'top center',end: 'bottom center',scrub: true}});
Core Concepts
Basic ScrollTrigger
javascript
gsap.to('.element', {x: 200,scrollTrigger: {trigger: '.element', // Element that triggers the animationstart: 'top center', // When trigger hits viewport centerend: 'bottom center', // When trigger leaves viewport centertoggleActions: 'play pause resume reset'}});
Start/End Positions
javascript
// Format: "trigger-position viewport-position"start: 'top center' // Trigger's top hits viewport centerstart: 'top 80%' // Trigger's top hits 80% down viewportstart: 'center center' // Trigger's center hits viewport centerstart: 'bottom top' // Trigger's bottom hits viewport topstart: 'top top+=100' // Trigger's top hits 100px below viewport top
Position Reference
| Value | Description | |
|---|---|---|
top | Top edge | |
center | Center | |
bottom | Bottom edge | |
80% | 80% from top | |
+=100 | Plus 100 pixels | |
-=50 | Minus 50 pixels |
Scrub Animations
Basic Scrub
javascript
// Animation progress tied to scroll positiongsap.to('.progress-bar', {scaleX: 1,scrollTrigger: {trigger: '.content',start: 'top top',end: 'bottom bottom',scrub: true // Directly linked to scroll}});
Smooth Scrub
javascript
gsap.to('.element', {x: 500,scrollTrigger: {trigger: '.section',scrub: 1, // 1 second smoothing// scrub: 0.5 // 0.5 second smoothing// scrub: 2 // 2 second smoothing (laggy feel)}});
Scrub with Timeline
javascript
const tl = gsap.timeline({scrollTrigger: {trigger: '.container',start: 'top top',end: '+=3000', // Scroll distancescrub: 1,pin: true}});tl.to('.step1', { opacity: 1 }).to('.step2', { opacity: 1 }).to('.step3', { opacity: 1 });
Pinning
Basic Pin
javascript
ScrollTrigger.create({trigger: '.panel',start: 'top top',end: '+=500', // Pin for 500px of scrollpin: true});
Pin with Animation
javascript
gsap.to('.content', {x: '-200%',ease: 'none',scrollTrigger: {trigger: '.horizontal-section',start: 'top top',end: () => '+=' + document.querySelector('.horizontal-section').offsetWidth,pin: true,scrub: 1}});
Pin Spacing
javascript
ScrollTrigger.create({trigger: '.section',pin: true,pinSpacing: true, // Default: adds space for pinned duration// pinSpacing: false // No extra space (content overlaps)// pinSpacing: '500px' // Custom spacing});
Toggle Actions
Action Syntax
javascript
// Format: "onEnter onLeave onEnterBack onLeaveBack"toggleActions: 'play pause resume reset'// Common combinations:toggleActions: 'play none none none' // Play oncetoggleActions: 'play reverse play reverse' // Toggle directiontoggleActions: 'restart none none none' // Restart each timetoggleActions: 'play complete reverse reset'
Action Values
| Action | Effect | |
|---|---|---|
play | Play forward | |
pause | Pause | |
resume | Resume from paused | |
reverse | Play backward | |
restart | Restart from beginning | |
reset | Reset to start (no animation) | |
complete | Jump to end | |
none | Do nothing |
Snap Points
Basic Snap
javascript
ScrollTrigger.create({trigger: '.sections',start: 'top top',end: 'bottom bottom',snap: 1 / 4 // Snap to quarters});
Snap to Labels
javascript
const tl = gsap.timeline({scrollTrigger: {trigger: '.container',scrub: 1,snap: {snapTo: 'labels',duration: 0.5,ease: 'power2.inOut'}}});tl.addLabel('intro').to('.a', { opacity: 1 }).addLabel('middle').to('.b', { opacity: 1 }).addLabel('end');
Snap Configuration
javascript
snap: {snapTo: [0, 0.25, 0.5, 0.75, 1], // Snap to specific pointsduration: { min: 0.2, max: 0.6 }, // Snap duration rangedelay: 0, // Delay before snapease: 'power1.inOut', // Snap easingdirectional: true // Snap in scroll direction}
Callbacks
ScrollTrigger Callbacks
javascript
ScrollTrigger.create({trigger: '.section',onEnter: () => console.log('Entered'),onLeave: () => console.log('Left'),onEnterBack: () => console.log('Entered from bottom'),onLeaveBack: () => console.log('Left going up'),onUpdate: (self) => console.log('Progress:', self.progress),onToggle: (self) => console.log('Active:', self.isActive),onRefresh: () => console.log('Refreshed')});
Progress-Based Updates
javascript
ScrollTrigger.create({trigger: '.section',start: 'top bottom',end: 'bottom top',onUpdate: (self) => {// self.progress: 0 to 1// self.direction: 1 (down) or -1 (up)// self.velocity: scroll speedupdateElement(self.progress);}});
Parallax Effects
Basic Parallax
javascript
// Background moves slower than scrollgsap.to('.background', {yPercent: -50,ease: 'none',scrollTrigger: {trigger: '.section',scrub: true}});// Foreground moves fastergsap.to('.foreground', {yPercent: 50,ease: 'none',scrollTrigger: {trigger: '.section',scrub: true}});
Multi-Layer Parallax
javascript
const layers = [{ selector: '.layer-1', speed: -20 },{ selector: '.layer-2', speed: -40 },{ selector: '.layer-3', speed: -60 },{ selector: '.layer-4', speed: -80 }];layers.forEach(layer => {gsap.to(layer.selector, {yPercent: layer.speed,ease: 'none',scrollTrigger: {trigger: '.parallax-section',start: 'top bottom',end: 'bottom top',scrub: true}});});
Horizontal Scrolling
Horizontal Section
javascript
const sections = gsap.utils.toArray('.panel');gsap.to(sections, {xPercent: -100 * (sections.length - 1),ease: 'none',scrollTrigger: {trigger: '.horizontal-container',pin: true,scrub: 1,snap: 1 / (sections.length - 1),end: () => '+=' + document.querySelector('.horizontal-container').offsetWidth}});
Markers (Development)
javascript
ScrollTrigger.create({trigger: '.section',start: 'top center',end: 'bottom center',markers: true, // Show visual markers// markers: { startColor: 'green', endColor: 'red', fontSize: '12px' }});
Batch Animations
Stagger on Scroll
javascript
ScrollTrigger.batch('.card', {onEnter: (elements) => {gsap.from(elements, {opacity: 0,y: 50,stagger: 0.1,duration: 0.5});},start: 'top 85%'});
Batch Configuration
javascript
ScrollTrigger.batch('.item', {interval: 0.1, // Time between batchesbatchMax: 3, // Max items per batchonEnter: batch => gsap.to(batch, { opacity: 1, y: 0, stagger: 0.1 }),onLeave: batch => gsap.to(batch, { opacity: 0, y: 20 }),onEnterBack: batch => gsap.to(batch, { opacity: 1, y: 0 }),onLeaveBack: batch => gsap.to(batch, { opacity: 0, y: -20 })});
Common Patterns
Reveal on Scroll
javascript
gsap.utils.toArray('.reveal').forEach(elem => {gsap.from(elem, {opacity: 0,y: 50,duration: 0.8,scrollTrigger: {trigger: elem,start: 'top 80%',toggleActions: 'play none none none'}});});
Progress Indicator
javascript
gsap.to('.progress-bar', {scaleX: 1,transformOrigin: 'left center',ease: 'none',scrollTrigger: {trigger: 'body',start: 'top top',end: 'bottom bottom',scrub: 0.3}});
Sticky Header Transform
javascript
ScrollTrigger.create({start: 'top -80',onUpdate: (self) => {if (self.direction === 1) {gsap.to('.header', { y: -80, duration: 0.3 });} else {gsap.to('.header', { y: 0, duration: 0.3 });}}});
Temporal Collapse Patterns
Countdown Scroll Reveal
javascript
// Reveal countdown sections as user scrollsconst sections = ['days', 'hours', 'minutes', 'seconds'];sections.forEach((section, i) => {gsap.from(`.countdown-${section}`, {opacity: 0,scale: 0.8,y: 50,duration: 0.8,ease: 'power3.out',scrollTrigger: {trigger: `.countdown-${section}`,start: 'top 80%',toggleActions: 'play none none none'}});});
Scroll-Based Time Dilation Effect
javascript
gsap.timeline({scrollTrigger: {trigger: '.time-section',start: 'top center',end: 'bottom center',scrub: 1}}).to('.time-digit', {textShadow: '0 0 50px #00F5FF, 0 0 100px #00F5FF',scale: 1.1}).to('.particles', {opacity: 1,filter: 'blur(0px)'}, '<');
Performance Tips
javascript
// Disable on mobile if neededScrollTrigger.matchMedia({'(min-width: 768px)': function() {// Desktop animations},'(max-width: 767px)': function() {// Simpler mobile animations}});// Refresh on resizeScrollTrigger.refresh();// Kill all ScrollTriggersScrollTrigger.killAll();// Kill specific triggerconst st = ScrollTrigger.create({ ... });st.kill();
Reference
- See
gsap-fundamentalsfor animation basics - See
gsap-sequencingfor timeline composition - See
gsap-reactfor React integration with ScrollTrigger