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.

PositionMeaning
(omitted)After the last tween (sequential)
0At the absolute start of the timeline
1.5At 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());