GSAP Cheatsheet
Timelines
Use this GSAP reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Creating a Timeline
const tl = gsap.timeline(); // With default vars (applied to all children unless overridden) const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2.out" }, repeat: -1, yoyo: true, paused: true, delay: 1, onComplete: () => console.log("done"), });
Chaining Tweens
Methods on a timeline return the timeline itself — chain everything.
const tl = gsap.timeline(); tl.to(".box", { x: 200, duration: 1 }) // plays at t=0 .to(".box", { y: 100, duration: 0.5 }) // plays AFTER previous .from(".text",{ opacity: 0, duration: 0.4 }) // plays AFTER previous .set(".badge",{ display: "block" }); // instant, plays AFTER previous
Position Parameter
The third argument to .to(), .from(), .fromTo(), .add() and .call() controls when in the timeline the tween starts.
| Position | Meaning |
|---|---|
| (omitted) | After the last tween (sequential) |
0 | At the absolute start of the timeline |
1.5 | At 1.5 seconds from the start |
"+=0.2" | 0.2s after the end of the last tween (gap) |
"-=0.2" | 0.2s before the end of the last tween (overlap) |
"<" | At the start of the previous tween |
"<0.2" | 0.2s after the start of the previous tween |
">" | At the end of the previous tween (same as omitting) |
">-0.2" | 0.2s before the end of the previous tween |
"myLabel" | At a named label |
"myLabel+=0.5" | 0.5s after a named label |
const tl = gsap.timeline(); // 0.2s overlap between tweens tl.to(".a", { x: 100, duration: 1 }) .to(".b", { y: 50, duration: 1 }, "-=0.2") // starts 0.2s early .to(".c", { scale: 2, duration: 0.5 }, "<"); // same start as .b // Absolute positioning tl.to(".a", { x: 100, duration: 1 }, 0) // at 0s .to(".b", { y: 50, duration: 1 }, 0.5) // at 0.5s .to(".c", { scale: 2 }, 2); // at 2s
Labels
const tl = gsap.timeline(); tl.to(".a", { x: 100 }) .addLabel("midpoint") // label at current end .to(".b", { y: 50 }) .to(".c", { opacity: 0 }, "midpoint") // plays at the label .to(".d", { scale: 2 }, "midpoint+=0.3"); // 0.3s after label // Add a label at a specific time tl.addLabel("intro", 1.5); // Seek to label tl.seek("midpoint"); // Add at end (same as no position arg) tl.addLabel("end", "+=0");
Nesting Timelines
function buildIntroTl() { return gsap.timeline() .from(".logo", { y: -30, opacity: 0 }) .from(".tagline",{ y: 20, opacity: 0 }, "-=0.2"); } function buildHeroTl() { return gsap.timeline() .from(".hero-img", { scale: 1.1 }) .from(".hero-text",{ x: -40, opacity: 0 }, "<0.1"); } // Master timeline composes sub-timelines with position param const master = gsap.timeline(); master.add(buildIntroTl()) .add(buildHeroTl(), "-=0.3"); // overlap slightly
Timeline Control Methods
const tl = gsap.timeline({ paused: true }); tl.play(); // play from current position tl.play(1.5); // play from 1.5s tl.pause(); // pause tl.pause(0.5); // pause AND seek to 0.5s tl.resume(); // resume from paused position tl.reverse(); // play backward from current position tl.reverse(0); // reverse from end tl.restart(); // restart from beginning tl.restart(true); // restart without delay tl.seek(2); // jump to 2s without affecting play state tl.seek("midpoint"); // jump to label tl.time(); // get current time tl.time(1.2); // set current time tl.progress(); // get 0–1 progress tl.progress(0.5); // seek to 50% tl.duration(); // total duration (read-only) tl.totalDuration(); // including repeats tl.timeScale(); // get speed multiplier tl.timeScale(2); // 2x speed tl.timeScale(0.5); // half speed tl.kill(); // destroy the timeline and all children tl.clear(); // remove all children (keeps timeline alive) tl.invalidate(); // flush cached start values (re-read live values)
Timeline Queries
// Get all direct children (tweens, nested timelines) tl.getChildren(); // [Tween, Timeline, ...] tl.getChildren(true, true, true); // (nested, tweens, timelines) // Get children tweening a specific target tl.getTweensOf(".box"); // Check if timeline is currently active tl.isActive(); // Duration tl.duration(); tl.totalDuration(); // accounts for repeat + repeatDelay
Timeline Repeat & Yoyo
const tl = gsap.timeline({ repeat: 3, // play 4 times total (1 + 3 repeats) repeat: -1, // loop forever repeatDelay: 0.5, // pause between repeats yoyo: true, // reverse direction on alternate repeats yoyoEase: "power1.in", // different ease on backward pass }); // Check repeat state in callbacks const tl = gsap.timeline({ repeat: -1, onRepeat() { console.log("repeat #", this.totalTime()); }, });
add() — insert anything at a position
tl.add(anotherTimeline, 1); // nest a timeline at 1s tl.add(gsap.to(".x", {y: 10}), "<"); // insert a tween tl.add(() => doSomething(), 2); // call a function at 2s (same as .call()) tl.add([tween1, tween2], 0.5); // insert multiple at same position
call() — schedule a function
tl.to(".box", { x: 200 }) .call(doSomething) // runs when previous tween ends .call(doSomethingWithArgs, ["a", "b"]) // pass args array .call(doSomething, null, "+=1"); // 1s after previous tween ends
Common Patterns
Staggered sequence
const tl = gsap.timeline(); tl.from(".item", { opacity: 0, y: 30, stagger: 0.1, // stagger is available on timeline children too duration: 0.5, });
Scrub / scroll-linked (with ScrollTrigger)
const tl = gsap.timeline({ scrollTrigger: { trigger: ".section", start: "top top", end: "bottom bottom", scrub: 1, }, }); tl.to(".parallax", { y: -150 }) .to(".fade", { opacity: 0 }, "<");
Master scene controller
const master = gsap.timeline({ paused: true }); master.add(introAnimation(), 0) .add(mainAnimation(), "+=0.5") .add(outroAnimation(), ">"); // Play on button click document.querySelector("#play").addEventListener("click", () => master.play()); document.querySelector("#back").addEventListener("click", () => master.reverse());