Lesson 18 / GSAP
GSAP Web Animation
Use GSAP for controlled JavaScript animation, sequenced timelines, staggered motion, and complex interaction patterns.
Course Role
Stretch
Good for students who are ready to go further after the core version works.
Teacher Notes / In-Class Use
Demo Live
- Walk through the interactive demo before students start changing their own project files.
- Connect the demo back to the first goal: Explain when GSAP is a better fit than CSS transitions or CSS animations
Try In Class
- Create one `gsap.to()` tween that moves an element with `x` or `y`.
- Have students make one visible change, save, refresh, and explain what changed.
Submit Or Check
- Ask students to show the work in the browser, not only in the editor.
- Have students commit their progress with a clear message when the checkpoint is stable.
Watch For
- Students copying code without checking file paths, spelling, or capitalization.
- Visual changes that work locally but break when the project is published.
Learning Goals
- Explain when GSAP is a better fit than CSS transitions or CSS animations
- Create tweens with `gsap.to()`, `gsap.from()`, and `gsap.fromTo()`
- Sequence animations with `gsap.timeline()` and stagger groups of elements
- Use GSAP with performance, accessibility, and reduced motion in mind
Interactive Demo
How to use this demo.
Use the demo as a small lab. Change one thing, observe the result, then connect it back to your own project.
What To Try
- Change duration, stagger, and easing before replaying the timeline.
- Compare how CSS-like motion decisions feel when controlled as a sequence.
What Changes
- Multiple elements animate as part of one coordinated timeline.
- The code sample updates with the timeline settings.
What To Notice
- GSAP is useful when motion needs sequencing and control beyond a single CSS transition.
- Staggering can make grouped elements feel organized instead of noisy.
Apply It
- Identify one place where a sequence would communicate better than everything moving at once.
Interactive Demo
GSAP Timeline Lab
Adjust the timeline settings and replay the sequence. The preview uses plain JavaScript, while the code shows the GSAP timeline you would write.
duration: 0.6s / stagger: 0.2s / ease: power2.out
const timeline = gsap.timeline();
timeline.from('.item', {
duration: 0.6,
opacity: 0,
y: 32,
stagger: 0.2,
ease: 'power2.out',
}); What to notice
- A timeline coordinates multiple animations as one sequence.
- Stagger creates a delay between similar elements.
- Ease changes the feel without changing the layout.
Try this
- Set stagger to 0, then replay the timeline.
- Compare power2.out with elastic.out.
- Copy the GSAP snippet into a page that loads GSAP.
This demo uses extra JavaScript for teaching. The code sample shows the pattern to practice. View full demo source.
Introduction
GSAP is a JavaScript animation library for controlling motion with code. It is useful when CSS transitions or CSS keyframes are not enough for the interaction you want to build.
Use GSAP when you need precise timing, sequences, staggered groups, scroll-based motion, or animations that respond to user interaction.
When to Use GSAP
Choose the simplest tool that handles the job. CSS is still the right choice for many small interactions. GSAP becomes helpful when the timing or interaction gets more complex.
| Need | Use | Why |
|---|---|---|
| Simple hover or focus change | CSS transition | The element moves between two states. |
| Simple repeating loader | CSS animation | A named @keyframes loop is enough. |
| Animate one element with JavaScript control | GSAP tween | gsap.to() can control timing, values, easing, and callbacks. |
| Sequence several steps | GSAP timeline | gsap.timeline() avoids manually managing delays. |
| Animate a group one after another | GSAP stagger | stagger creates a clean sequence across many elements. |
| Scroll-based animation | GSAP ScrollTrigger | Scroll progress and animation timing need tighter control. |
Getting Started with GSAP
You can load GSAP from a CDN for small demos. In larger projects, you may install it through your package manager.
A tween is one animation instruction. It needs a target, properties to animate, and timing options such as duration and ease.
GSAP x and y use transforms. They are usually better for motion than animating layout properties such as left or top.
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
<div class="box">Animate me</div>
<script>
gsap.to('.box', {
x: 100,
rotation: 360,
duration: 1,
});
</script> Tween Basics
| Piece | Meaning | Example |
|---|---|---|
| Target | The element or elements to animate | '.card' |
| Properties | The values that change | x, opacity, scale |
| Duration | How long the tween takes | duration: 0.6 |
| Ease | How the motion speeds up or slows down | ease: 'power2.out' |
| Delay | How long to wait before starting | delay: 0.2 |
| Callback | A function that runs during the tween lifecycle | onComplete |
Common GSAP Properties
| Property | Use For |
|---|---|
x and y | Move an element with transforms. |
rotation | Rotate an element. |
scale | Resize an element visually. |
opacity | Fade an element in or out. |
duration | Set how long the tween takes. |
ease | Control the feel of the motion. |
delay | Wait before starting. |
stagger | Offset the start time across multiple elements. |
`gsap.to()`
gsap.to() animates from the element's current state to the values you provide.
gsap.to('.box', {
x: 120,
opacity: 0.5,
duration: 0.6,
ease: 'power2.out',
}); `gsap.from()`
gsap.from() starts at the values you provide and animates to the element's current CSS state. This is useful for entrance animations.
gsap.from('.card', {
y: 30,
opacity: 0,
duration: 0.6,
ease: 'power2.out',
}); `gsap.fromTo()`
gsap.fromTo() lets you define both the starting values and ending values. Use it when you need complete control over both states.
gsap.fromTo(
'.button',
{ scale: 0.8, opacity: 0 },
{ scale: 1, opacity: 1, duration: 0.4 }
); Timelines
gsap.timeline() lets you sequence multiple tweens without calculating all the delays by hand.
Each tween is added to the timeline. By default, the next tween starts after the previous tween ends.
const timeline = gsap.timeline();
timeline
.to('.box', { x: 100, duration: 0.5 })
.to('.box', { rotation: 180, duration: 0.5 })
.to('.box', { scale: 1.2, duration: 0.5 }); Timeline Position Controls
Timeline position values control when a tween starts. This is one of the biggest reasons to use GSAP for sequenced motion.
| Position | Meaning |
|---|---|
| No position value | Start after the previous tween ends. |
'<' | Start at the same time as the previous tween. |
'-=0.2' | Start 0.2 seconds before the previous tween ends. |
'+=0.2' | Start 0.2 seconds after the previous tween ends. |
const timeline = gsap.timeline();
timeline
.to('.card', { y: -12, duration: 0.3 })
.to('.card', { opacity: 1, duration: 0.3 }, '<')
.to('.badge', { scale: 1, duration: 0.2 }, '-=0.1'); Staggered Tweens
stagger animates a group of elements with a delay between each element. This is great for card grids, navigation items, galleries, and lists.
gsap.from('.gallery-card', {
y: 24,
opacity: 0,
duration: 0.45,
ease: 'power2.out',
stagger: 0.08,
}); Easing
ease changes the feel of the motion. Start with common values such as power2.out, power2.inOut, or sine.inOut before using more dramatic easing.
gsap.to('.panel', {
y: 0,
opacity: 1,
duration: 0.5,
ease: 'power2.out',
}); Callbacks
Callbacks run functions at different points in a tween. Use them when animation needs to coordinate with interface state.
gsap.to('.notification', {
y: 0,
opacity: 1,
duration: 0.3,
onStart: () => console.log('Animation started'),
onComplete: () => console.log('Animation complete'),
}); Repeat and Yoyo
repeat controls how many times a tween repeats. yoyo makes alternate repeats play backward.
Use infinite motion carefully. Repeated motion should have a clear purpose and should respect reduced-motion preferences.
gsap.to('.pulse', {
scale: 1.12,
duration: 0.8,
repeat: 3,
yoyo: true,
ease: 'sine.inOut',
}); Reduced Motion with GSAP
Check prefers-reduced-motion before running non-essential animation. You can skip the animation, shorten it, or set final states immediately.
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduceMotion) {
gsap.set('.card', { opacity: 1, y: 0 });
} else {
gsap.from('.card', {
opacity: 0,
y: 24,
duration: 0.5,
stagger: 0.08,
});
} Plugins
GSAP plugins extend what GSAP can do. Use plugins when the core tween and timeline tools are not enough.
| Plugin | Use For |
|---|---|
ScrollTrigger | Starting or controlling animation based on scroll position. |
MorphSVG | Morphing SVG shapes. |
SplitText | Animating words, lines, or characters. |
DrawSVG | Revealing SVG strokes progressively. |
Advanced Performance Notes
For most beginner work, animate x, y, scale, rotation, and opacity. These map well to transform and opacity-based motion.
Tools like overwrite, force3D, and CSS will-change can help in specific cases, but they should not be the first thing you reach for.
overwrite: autocan help when multiple tweens compete for the same properties.force3D: truecan encourage GPU rendering, but overusing it can hurt performance.will-changecan prepare the browser for animation, but leaving it everywhere can waste memory.
gsap.to('.box', {
x: 200,
duration: 1,
overwrite: 'auto',
}); Common Mistakes
| Mistake | Why It Hurts | Fix |
|---|---|---|
| Using GSAP when CSS is enough | Adds complexity for a simple state change | Use CSS transitions or animations for simple effects. |
Animating left or top | Can trigger layout recalculation | Use GSAP x and y instead. |
| Running code before elements exist | GSAP cannot find the target | Run scripts after the DOM is ready or place scripts after the HTML. |
| Forgetting reduced motion | Some users are sensitive to motion | Check prefers-reduced-motion and simplify or skip animation. |
| Overusing infinite motion | Constant motion can distract users | Use repeat purposefully and avoid unnecessary loops. |
| Not cleaning up complex animations | Repeated setup can cause bugs in larger apps | Kill scroll triggers or repeated timelines when components are removed. |
Checkpoint
Before moving on, make sure these feel true.
- I can explain the main concept in my own words.
- I can apply this lesson to my current project.
- I can verify the result in the browser.
- I can commit the change with a clear message.
Project Connection
This lesson supports current class projects.
Practice
- Create one
gsap.to()tween that moves an element withxory. - Create one
gsap.from()entrance animation usingopacityandy. - Build a three-step
gsap.timeline()sequence. - Stagger a group of cards or list items.
- Add
repeatandyoyoto one purposeful effect. - Add a
prefers-reduced-motioncheck that skips or simplifies motion. - Explain why GSAP was a better choice than CSS for one example.
Resources
- GSAP CDN
- GSAP Ease Visualizer
- GSAP Plugins Page