| name | gsap-core |
| description | Use when implementing GSAP core animations, tweens, timeline sequencing, playback controls, or when using gsap.to(), gsap.from(), gsap.fromTo(), gsap.set(), gsap.timeline(). |
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.
gsap.to('.box', {
x: 200,
opacity: 0.5,
duration: 1.5,
ease: 'power2.out'
})
gsap.to('.element', {
x: 100,
y: 50,
rotation: 90,
scale: 1.2,
backgroundColor: '#ff0000',
duration: 1
})
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.
gsap.from('.hero', {
opacity: 0,
y: 100,
duration: 1,
ease: 'back.out(1.7)'
})
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 }
)
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.
gsap.set('.box', { opacity: 0 })
gsap.set('.item', {
x: (i) => i * 100,
y: (i) => i * 50
})
gsap.set('.element', {
display: 'flex',
opacity: 0,
y: 20
})
Timeline Methods
Creating Timelines
const tl = gsap.timeline()
const tl = gsap.timeline({
paused: true,
repeat: -1,
yoyo: true,
defaults: { ease: 'power2.out', duration: 1 }
})
const tl = gsap.timeline({
scrollTrigger: {
trigger: '.section',
start: 'top center',
scrub: true
}
})
Chaining Tweens
const tl = gsap.timeline()
tl.to('.box1', { x: 100, duration: 1 })
.to('.box2', { x: 100, duration: 1 })
tl.to('.box1', { x: 100, duration: 1 })
.to('.box2', { x: 100, duration: 1 }, '-=0.5')
tl.to('.box1', { x: 100, duration: 1 })
.to('.box2', { x: 100, duration: 1 }, '<')
.to('.box3', { y: 100, duration: 1 }, '<0.2')
Timeline Positioning
const tl = gsap.timeline()
tl.to('.box1', { x: 100 })
.addLabel('step1')
.to('.box2', { x: 100 }, 'step1')
.to('.box3', { x: 100 }, 'step1+=0.5')
.to('.box4', { x: 100 }, 'step1-=0.2')
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()
tl.play()
tl.play(0.5)
tl.play('step1')
tl.pause()
tl.pause(0.5)
tl.reverse()
tl.reverse(0.5)
tl.progress(0)
tl.progress(0.5)
tl.progress(1)
tl.timeScale(1)
tl.timeScale(2)
tl.timeScale(0.5)
tl.animationProgress(0.5)
tl.totalProgress(0.75)
tl.restart()
tl.kill()
Special Properties
Core Tween Properties
gsap.to('.box', {
duration: 1,
delay: 0.5,
ease: 'power2.out',
repeat: 2,
repeatDelay: 0.5,
yoyo: true,
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,
transformOrigin: 'center center',
immediateRender: false,
lazy: true,
overwrite: 'auto',
id: 'myAnimation',
data: { custom: 'value' }
})
Stagger Animations
Basic Stagger
gsap.to('.box', {
x: 100,
stagger: 0.1
})
gsap.to('.box', {
x: 100,
stagger: {
each: 0.1,
from: 'start',
grid: [4, 4],
ease: 'power2.out'
}
})
Stagger Patterns
gsap.from('.item', {
opacity: 0,
scale: 0,
stagger: {
each: 0.05,
from: 'center',
ease: 'back.out(1.7)'
}
})
gsap.to('.grid-item', {
rotation: 90,
stagger: {
each: 0.1,
from: 'center',
grid: [5, 5],
ease: 'power2.inOut'
}
})
gsap.to('.wave-item', {
y: -50,
stagger: {
each: 0.05,
from: 'start',
ease: 'sine.out'
}
})
Keyframes
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,
easeEach: 'power1.out'
})
Callbacks
gsap.to('.box', {
x: 100,
duration: 1,
onStart: function() {
console.log(this.targets())
},
onUpdate: function() {
console.log(this.progress())
},
onComplete: function() {
console.log('Done!')
},
onRepeat: function() {
console.log('Repeating...')
},
onReverseComplete: function() {
console.log('Reverse done!')
},
onStartParams: ['param1', 'param2'],
onUpdateScope: myObject,
onCompleteScope: myObject
})
Instance Methods
const tween = gsap.to('.box', { x: 100 })
tween.play()
tween.pause()
tween.resume()
tween.reverse()
tween.restart()
tween.kill()
tween.progress(0.5)
tween.time(0.5)
tween.timeScale(2)
tween.pause()
tween.paused(true)
tween.invalidate()
tween.targets()
tween.timeline()
tween.id
tween.kill()
tween.kill(vars)
Global Methods
gsap.killTweensOf('.box')
gsap.killTweensOf('.box', 'x')
gsap.killTweensOf('.box', { x: true })
gsap.defaults({
ease: 'power2.out',
duration: 1
})
const mm = gsap.matchMedia()
mm.add('(min-width: 768px)', () => {
gsap.to('.box', { x: 200 })
})
mm.add('(max-width: 767px)', () => {
gsap.to('.box', { x: 100 })
})
mm.revert()
const tween = gsap.getById('myAnimation')
gsap.ticker.add(callback)
gsap.ticker.remove(callback)
gsap.ticker.lagSmoothing(1000)
tl = gsap.()
. = 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: () => {
}
})
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')
tl.play('start')
Common Mistakes
1. Forgetting to Register Plugins
import { ScrollTrigger } from 'gsap/ScrollTrigger'
gsap.to('.box', { scrollTrigger: { ... } })
gsap.registerPlugin(ScrollTrigger)
gsap.to('.box', { scrollTrigger: { ... } })
2. Conflicting Tweens
gsap.to('.box', { x: 100, duration: 2 })
gsap.to('.box', { x: 200, duration: 1 })
gsap.to('.box', { x: 100, duration: 2, overwrite: true })
gsap.killTweensOf('.box', 'x')
gsap.to('.box', { x: 200, duration: 1 })
3. from() Flash
gsap.from('.box', { opacity: 0 })
gsap.to('.box', { opacity: 1 })
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 |