gsap-core
Installation
SKILL.md
GSAP Core - Tweens and Timelines
GSAP's core provides the fundamental building blocks for animation: tweens (single animations) and timelines (sequences of tweens). This skill covers all core methods, playback controls, and best practices.
Installation
npm install gsap
import gsap from 'gsap'
Core Tween Methods
gsap.to(target, vars)
Animate from current values to new end values. Most commonly used method.
// Basic animation
gsap.to('.box', {
x: 200,
opacity: 0.5,
duration: 1.5,
ease: 'power2.out'
})
// Multiple properties
gsap.to('.element', {
x: 100,
y: 50,
rotation: 90,
scale: 1.2,
backgroundColor: '#ff0000',
duration: 1
})
// Array of targets
gsap.to('.box', {
x: 100,
duration: 1,
stagger: 0.1
})
gsap.from(target, vars)
Animate from defined start values to current values. Ideal for entrance effects.
// Element fades in from below
gsap.from('.hero', {
opacity: 0,
y: 100,
duration: 1,
ease: 'back.out(1.7)'
})
// Elements animate from scattered positions
gsap.from('.particle', {
x: () => gsap.utils.random(-200, 200),
y: () => gsap.utils.random(-200, 200),
scale: 0,
duration: 1,
stagger: 0.05,
ease: 'elastic.out(1, 0.3)'
})
gsap.fromTo(target, fromVars, toVars)
Explicitly control both start and end values. Maximum control.
gsap.fromTo('.box',
{ opacity: 0, x: -100 },
{ opacity: 1, x: 0, duration: 1 }
)
// Perfect for state transitions
gsap.fromTo('.modal',
{ opacity: 0, scale: 0.8, y: 50 },
{ opacity: 1, scale: 1, y: 0, duration: 0.3, ease: 'back.out' }
)
gsap.set(target, vars)
Instantly apply values without duration (zero-duration tween). Good for initial states.
// Set initial state
gsap.set('.box', { opacity: 0 })
// Position elements without animation
gsap.set('.item', {
x: (i) => i * 100,
y: (i) => i * 50
})
// Set multiple properties
gsap.set('.element', {
display: 'flex',
opacity: 0,
y: 20
})
Timeline Methods
Creating Timelines
// Basic timeline
const tl = gsap.timeline()
// Timeline with defaults
const tl = gsap.timeline({
paused: true,
repeat: -1,
yoyo: true,
defaults: { ease: 'power2.out', duration: 1 }
})
// Timeline with ScrollTrigger
const tl = gsap.timeline({
scrollTrigger: {
trigger: '.section',
start: 'top center',
scrub: true
}
})
Chaining Tweens
const tl = gsap.timeline()
// Sequential animations
tl.to('.box1', { x: 100, duration: 1 })
.to('.box2', { x: 100, duration: 1 })
// Overlapping animations
tl.to('.box1', { x: 100, duration: 1 })
.to('.box2', { x: 100, duration: 1 }, '-=0.5') // Start 0.5s before previous ends
// Same start time
tl.to('.box1', { x: 100, duration: 1 })
.to('.box2', { x: 100, duration: 1 }, '<') // Start with previous
.to('.box3', { y: 100, duration: 1 }, '<0.2') // Start 0.2s after previous
Timeline Positioning
const tl = gsap.timeline()
tl.to('.box1', { x: 100 })
.addLabel('step1') // Add label
.to('.box2', { x: 100 }, 'step1') // Start at label
.to('.box3', { x: 100 }, 'step1+=0.5') // 0.5s after label
.to('.box4', { x: 100 }, 'step1-=0.2') // 0.2s before label
Position strings:
"<": Start at same time as previous animation">": Start after previous animation ends"<0.5": Start 0.5s before previous ends">0.5": Start 0.5s after previous ends"label": Start at specific label"label+=0.5": Start 0.5s after label"label-=0.5": Start 0.5s before label
Playback Control Methods
const tl = gsap.timeline()
// Play
tl.play()
tl.play(0.5) // Play from 0.5 seconds
tl.play('step1') // Play from label
// Pause
tl.pause()
tl.pause(0.5)
// Reverse
tl.reverse()
tl.reverse(0.5)
// Progress control (0-1)
tl.progress(0) // Start
tl.progress(0.5) // Halfway
tl.progress(1) // End
// Time scale (speed)
tl.timeScale(1) // Normal speed
tl.timeScale(2) // 2x faster
tl.timeScale(0.5) // 2x slower
// Animation in place (pause after completing)
tl.animationProgress(0.5)
// Total progress (including repeats)
tl.totalProgress(0.75)
// Restart
tl.restart()
// Kill
tl.kill()
Special Properties
Core Tween Properties
gsap.to('.box', {
// Duration
duration: 1, // Seconds
delay: 0.5, // Delay before start
// Easing
ease: 'power2.out', // See gsap-easing skill
// Repeats
repeat: 2, // Number of repeats
repeatDelay: 0.5, // Delay between repeats
yoyo: true, // Alternate direction each repeat
// Callbacks
onStart: () => console.log('Started'),
onUpdate: () => console.log('Updating'),
onComplete: () => console.log('Complete'),
onRepeat: () => console.log('Repeating'),
onReverseComplete: () => console.log('Reverse complete')
})
Advanced Properties
gsap.to('.box', {
x: 100,
y: 50,
rotation: 90,
scale: 1.5,
opacity: 0.5,
// Transform origin
transformOrigin: 'center center',
// Immediate render
immediateRender: false, // Don't render immediately
// Lazy rendering
lazy: true, // Don't render until needed
// Overwrite behavior
overwrite: 'auto', // 'auto', 'true', false
// ID for reference
id: 'myAnimation',
// Data storage
data: { custom: 'value' }
})
Stagger Animations
Basic Stagger
// Delay between elements
gsap.to('.box', {
x: 100,
stagger: 0.1 // 0.1s delay between each
})
// Stagger with options
gsap.to('.box', {
x: 100,
stagger: {
each: 0.1, // Delay between each
from: 'start', // 'start', 'center', 'end', 'edges'
grid: [4, 4], // Grid dimensions for pattern
ease: 'power2.out' // Easing for stagger
}
})
Stagger Patterns
// From center
gsap.from('.item', {
opacity: 0,
scale: 0,
stagger: {
each: 0.05,
from: 'center',
ease: 'back.out(1.7)'
}
})
// Grid stagger
gsap.to('.grid-item', {
rotation: 90,
stagger: {
each: 0.1,
from: 'center',
grid: [5, 5], // 5x5 grid
ease: 'power2.inOut'
}
})
// Wave pattern
gsap.to('.wave-item', {
y: -50,
stagger: {
each: 0.05,
from: 'start',
ease: 'sine.out'
}
})
Keyframes
// Multiple stages in one tween
gsap.to('.box', {
keyframes: [
{ x: 100, duration: 1, ease: 'power1.inOut' },
{ y: 100, duration: 1, ease: 'power1.inOut' },
{ x: 0, y: 0, duration: 1, ease: 'power1.inOut' }
],
duration: 3, // Total duration if not specified per key
easeEach: 'power1.out' // Apply ease to each keyframe
})
Callbacks
gsap.to('.box', {
x: 100,
duration: 1,
// Lifecycle callbacks
onStart: function() {
console.log(this.targets()) // Access targets
},
onUpdate: function() {
console.log(this.progress()) // Current progress
},
onComplete: function() {
console.log('Done!')
},
onRepeat: function() {
console.log('Repeating...')
},
onReverseComplete: function() {
console.log('Reverse done!')
},
// Parameters
onStartParams: ['param1', 'param2'],
onUpdateScope: myObject,
onCompleteScope: myObject
})
Instance Methods
const tween = gsap.to('.box', { x: 100 })
// Control methods
tween.play()
tween.pause()
tween.resume()
tween.reverse()
tween.restart()
tween.kill()
// Progress control
tween.progress(0.5)
tween.time(0.5)
// Rate
tween.timeScale(2)
// Pause/resume
tween.pause()
tween.paused(true)
// Invalidate (force recalculation)
tween.invalidate()
// Get targets
tween.targets()
// Get timeline
tween.timeline()
// Get ID
tween.id
// Kill
tween.kill()
tween.kill(vars) // Kill specific properties
Global Methods
// Kill all tweens
gsap.killTweensOf('.box')
gsap.killTweensOf('.box', 'x') // Kill only x tweens
gsap.killTweensOf('.box', { x: true })
// Global defaults
gsap.defaults({
ease: 'power2.out',
duration: 1
})
// Match media (responsive)
const mm = gsap.matchMedia()
mm.add('(min-width: 768px)', () => {
gsap.to('.box', { x: 200 })
})
mm.add('(max-width: 767px)', () => {
gsap.to('.box', { x: 100 })
})
// Revert all match media
mm.revert()
// Get tween by ID
const tween = gsap.getById('myAnimation')
// Global ticker
gsap.ticker.add(callback)
gsap.ticker.remove(callback)
gsap.ticker.lagSmoothing(1000) // Adjust lag smoothing
// Export timeline (for external control)
const tl = gsap.timeline()
window.myAnimation = tl
Quick Patterns
Entrance Animation
gsap.from('.hero', {
opacity: 0,
y: 50,
duration: 1,
ease: 'power2.out'
})
Exit Animation
gsap.to('.modal', {
opacity: 0,
scale: 0.9,
duration: 0.3,
ease: 'power2.in',
onComplete: () => {
// Remove element
}
})
Hover Effect
const hoverTween = gsap.to('.button', {
scale: 1.1,
duration: 0.3,
ease: 'power2.out',
paused: true
})
document.querySelector('.button').addEventListener('mouseenter', () => hoverTween.play())
document.querySelector('.button').addEventListener('mouseleave', () => hoverTween.reverse())
Sequence with Labels
const tl = gsap.timeline()
tl.addLabel('start')
.to('.box1', { x: 100 }, 'start')
.to('.box2', { x: 100 }, 'start+=0.5')
.to('.box3', { x: 100 }, 'start+=1')
.addLabel('end')
// Jump to label
tl.play('start')
Common Mistakes
1. Forgetting to Register Plugins
// ❌ Wrong
import { ScrollTrigger } from 'gsap/ScrollTrigger'
gsap.to('.box', { scrollTrigger: { ... } })
// ✅ Correct
gsap.registerPlugin(ScrollTrigger)
gsap.to('.box', { scrollTrigger: { ... } })
2. Conflicting Tweens
// ❌ Conflicting
gsap.to('.box', { x: 100, duration: 2 })
gsap.to('.box', { x: 200, duration: 1 })
// ✅ Use overwrite
gsap.to('.box', { x: 100, duration: 2, overwrite: true })
// ✅ Or kill first
gsap.killTweensOf('.box', 'x')
gsap.to('.box', { x: 200, duration: 1 })
3. from() Flash
// ❌ Element flashes before animation
gsap.from('.box', { opacity: 0 })
// ✅ Set initial state in CSS
// CSS: .box { opacity: 0; }
gsap.to('.box', { opacity: 1 })
// ✅ Or use fromTo
gsap.fromTo('.box',
{ opacity: 0 },
{ opacity: 1, duration: 1 }
)
Best Practices
- Use timelines for sequences - Easier to control and maintain
- Leverage stagger - Creates smoother, more engaging animations
- Use callbacks wisely - Don't overuse, keep logic simple
- Clean up animations - Kill tweens/timelines when no longer needed
- Use matchMedia - Make animations responsive
- Set appropriate eases - Match animation to feel (see gsap-easing)
- Avoid over-animating - Keep animations purposeful and performant
Quick Reference
| Task | Method |
|---|---|
| Animate to values | gsap.to(target, { props }) |
| Animate from values | gsap.from(target, { props }) |
| Animate both | gsap.fromTo(target, { from }, { to }) |
| Set instantly | gsap.set(target, { props }) |
| Create timeline | gsap.timeline({ options }) |
| Kill tweens | gsap.killTweensOf(target) |
| Global defaults | gsap.defaults({ props }) |
| Match media | gsap.matchMedia() |
| Get tween | gsap.getById(id) |
| Ticker | gsap.ticker |
Weekly Installs
1
Repository
microck/gsap-skillsFirst Seen
6 days ago
Security Audits
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
warp1