Command Palette

Search for a command to run...

Hectal
Shots in this scene
SHOT 14.2Advanced ~19 min · shot 2 of 7

Timelines and the Position Parameter

In one line

A timeline is a container of tweens placed on one clock. The position parameter says where each one goes (after the last, with it, at a label), and the timeline can then be played, reversed, sought and slowed as one thing.

0/7 · 0%

Think of it like this

A film editor's timeline. Clips sit on one strip: this one starts when the last ends, that one overlaps it by a second, one starts at the marker named "chorus". Move the marker and every clip pinned to it moves too. A GSAP timeline is that strip for animation.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

timeline
A container that places tweens (and other timelines) on one clock, so they can be played, reversed and seeked as one.
position parameter
The last argument of a tween added to a timeline: where it starts ("<", "+=0.3", a number or a label).
label
A name for a time in a timeline, used as an anchor for positions and for seek().
playhead
The timeline's current time, like the marker on a video's progress bar.

Step by step

01Read the positions before you play

Open "One timeline, four steps". The console prints where each child starts: 0, 0.5, 0.7 and 1.5 seconds, and the total, 2 seconds. Nothing has played yet, because the timeline was made with paused: true. Each number comes from its position string. The headline has none, so it starts at 0. The label volt names 0.5 s, the end of the headline, and the Volt sits at it. The price is "<0.2": 0.2 s after the Volt starts, so 0.7 s. The button is "+=0.3": 0.3 s after the end of everything so far (1.2 s), so 1.5 s.

02Play it and step to the label

Press Play, pause, and step. There are four tracks, one per tween, each offset on the ruler. Press Seek “volt”: the headline is complete and the others are still hidden, because from() hid them as soon as they were added.

03Change one number and watch the rest follow

Change "<0.2" to "<". The price now starts with the Volt at 0.5 s. Everything after it moves earlier with it, and the total drops to 1.8 s. No other number changed.

04Reverse and slow it down

After it has played, press Reverse: it runs backward through the same tracks. Speed 0.25× runs the whole timeline at a quarter of the speed (timeScale).

Try it yourself

  1. 1

    Start the price with the Volt

    In "One timeline, four steps" change "<0.2" to "<". The console now says child 2 starts at 0.5 s (not 0.7), child 3 at 1.3 s, and the duration is 1.8 s.

  2. 2

    Overlap the last step

    Change "+=0.3" to "-=0.3". The Reserve button now starts at 0.9 s (1.2 s, the end so far, minus 0.3), and the duration is 1.4 s.

  3. 3

    Reverse past a callback

    Change the call position ">" to 1.2, press Play, wait for done, then Reverse: done prints a second time when the playhead crosses 1.2 going back. With ">" (the very end) it does not, because the reverse starts on the callback.

Code & diagrams

One timeline, four steps

Read the console first: it prints each tween's start and the label. Then play, reverse, seek the label and slow it down.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

child 0: starts 0 s, lasts 0.5 s
child 1: starts 0.5 s, lasts 0.5 s
child 2: starts 0.7 s, lasts 0.5 s
child 3: starts 1.5 s, lasts 0.5 s
child 4: starts 2 s, lasts 0 s
labels: {"volt":0.5}  duration: 2 s

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Misspell a label in a position

In "One timeline, four steps" change "<0.2" to "vlot+=0.2".

terminal
$ Read the console
── what you'll see ──
child 2: starts 1.2 s, lasts 0.5 s
child 3: starts 2 s, lasts 0.5 s
labels: {"volt":0.5,"vlot":1} duration: 2.5 s

Break #2

Two tweens on one property with different lengths

Write gsap.to("#x", { x: 200, duration: 2, ease: "none" }) and then gsap.to("#x", { x: 100, duration: 1, ease: "none" }) with no overwrite.

terminal
$ Read #x's transform at 1 s, 1.1 s and 1.5 s
── what you'll see ──
x = 100 when the second tween ends, then climbing 100 px per second: about 110 at 1.1 s, 150 at 1.5 s, 200 at 2 s (measured)

Myth vs fact

Myth

A timeline is just a list of delays.

Fact

Positions are relative to other tweens and labels, so one change moves what follows. Delays are absolute numbers you must recompute by hand.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    A timeline's children sit on its own clock, and the timeline sits on the global timeline. So pausing the global timeline (as the Motion Timeline does) pauses every nested one, and timeScale multiplies down the chain.

Remember this

  1. 1

    The problem this solves: with CSS you sequence by delays: 0 s, 0.5 s, 0.7 s, 1.5 s. When the first step gets 0.2 s longer you must change every number after it. A timeline places each tween relative to the others, so retiming one step moves the rest, and the whole sequence has one play button.

  2. 2

    Making one. gsap.timeline({ defaults: { duration: 0.5, ease: "power2.out" } }) creates it. defaults are copied into every tween you add. Chain .from(), .to() and .fromTo() onto it: they are the same verbs as Topic 14.1, but they land on the timeline's clock instead of the page's.

  3. 3

    The position parameter is the last argument. With none, a tween starts right after the previous one ends. A number is an absolute time in seconds. "+=0.3" is 0.3 s after the end of everything so far, and "-=0.3" overlaps by 0.3 s. "<" is the start of the previous tween and ">" its end, and "<0.2" means 0.2 s after that start. "volt" is a label, and "volt+=0.3" is 0.3 s after it.

  4. 4

    Labels are names for times: tl.addLabel("volt") names "now" (the end so far), tl.addLabel("volt", 0.5) names 0.5 s. Tweens placed at a label move with it, and tl.seek("volt") jumps there, so a designer can retime one place.

  5. 5

    Controlling it. play(), pause(), reverse(), restart(), seek(time or label), progress(0 to 1), timeScale(0.5) and time() work on the whole timeline. A timeline can hold other timelines: tl.add(otherTimeline, "label") nests it. A callback added with call() fires each time the playhead crosses it, forward or back.

  6. 6

    Two tweens on one property. Both write it every frame: the later one wins until it ends, then the earlier one carries on. overwrite: "auto" kills only the clashing properties of earlier running tweens, overwrite: true kills all tweens of that target, and the default false kills nothing.

Explain it without notes

01

Explain "<", ">", "+=0.3" and "label+=0.3" as positions.

02

Two tweens animate x on one element and the second one ends first. What does the user see, and how do you prevent it?

Practice

01

Write a timeline in which the headline fades in over 0.6 s, the Volt slides in starting 0.2 s before the headline ends, and a button appears 0.5 s after both are finished. Print its duration.

02

Make a label "ready" at the end of the Volt's entrance, add a tween at "ready+=0.4", and write one line that jumps to the label.

Done when you can

  • You can place a tween with "<", "+=", a number and a label

  • You can control a timeline with play, reverse, seek, progress and timeScale

  • You can say which overwrite mode keeps which tweens