The secret to building gorgeous sequences with precise timing is understanding the position parameter which is used in many methods throughout TimelineLite/Max. This one super-flexible parameter controls the placement of your tweens, labels, callbacks, pauses, and even nested timelines, so you'll be able to literally place anything anywhere in any sequence.

Watch the video

Using position with TimelineLite.to()

This article will focus on the TimelineLite.to() method for adding tweens to a TimelineLite, but it works the same in other methods like from(), fromTo(), add(), etc. Notice that the position parameter comes after the vars parameter:

.to( target, duration, vars, position )

Since it's so common to chain animations one-after-the-other, the default position is "+=0" which just means "at the end", so timeline.to(...).to(...) chains those animations back-to-back. It's fine to omit the position parameter in this case. But what if you want them to overlap, or start at the same time, or have a gap between them? No problem.

Multiple behaviors

You can define the position in any of the following ways:

  • at an absolute time (1)
  • relative to the end of a timeline allowing for gaps ("+=1") or overlaps ("-=1")
  • at a label ("someLabel")
  • relative to a label ("someLabel+=1")

Basic code usage

tl.to(element, 1, {x:200})
  //1 second after end of timeline (gap)
  .to(element, 1, {y:200}, "+=1")
  //0.5 seconds before end of timeline (overlap)
  .to(element, 1, {rotation:360}, "-=0.5")
  //at exactly 6 seconds from the beginning of the timeline
  .to(element, 1, {scale:4}, 6);

It can also be used to add tweens at labels or relative to labels

//add a label named scene1 at an exact time of 2-seconds into the timeline
tl.add("scene1", 2)
  //add tween at scene1 label
  .to(element, 4, {x:200}, "scene1")
  //add tween 3 seconds after scene1 label
  .to(element, 1, {opacity:0}, "scene1+=3");

Sometimes technical explanations and code snippets don't do these things justice. Take a look at the interactive examples below.

No position: Direct Sequence

If no position parameter is provided, all tweens will run in direct succession.

1.0
1
2
3
4
  
//all tweens run in direct succession
var tl = new TimelineLite();
tl.to("#green", 1, {x:750})
  .to("#blue", 1, {x:750})
  .to("#orange", 1, {x:750})
  

Positive Relative: Gaps / Delays

Use a positive, relative value ("+=X") to place your tween X seconds after previous animations end

1.0
1
2
3
4
  
//there is a 1 second gap between tweens
var tl = new TimelineLite();
tl.to("#green", 1, {x:750})
  // insert 1 second after end of timeline
  .to("#blue", 1, {x:750}, "+=1")
  // insert 1 second after end of timeline
  .to("#orange", 1, {x:750}, "+=1")
  

Negative Relative: Overlap

Use a negative, relative value ("-=X") to place your tween X seconds before previous animations end

1.0
1
2
3
4
  
//tweens overlap
var tl = new TimelineLite();
tl.to("#green", 2, {x:750})
   // insert 1 second before end of timeline
  .to("#blue", 2, {x:750}, "-=1")
   // insert 1 second before end of timeline
  .to("#orange", 2, {x:750}, "-=1");
  

Absolute: Anywhere

Use an absolute value (number) to specify the exact time in seconds a tween should start.

1.0
1
2
3
4
  
//tweens are inserted at absolute position
var tl = new TimelineLite();
tl.to("#green", 4, {x:750})
  //insert tween 1 second into timeline
  .to("#blue", 2, {x:750}, 1)
  //insert tween 1 second into timeline
  .to("#orange", 2, {x:750}, 1);
  

Labels

Use a label ("string") to specify where a tween should be placed.

1.0
blueGreenSpin
1
2
3
4
  
//tweens are inserted at and relative to a label's position
var tl = new TimelineLite();
tl.to("#green", 1, {x:750})
  //add blueGreenSpin label 1 second after end of timeline
  .add("blueGreenSpin", "+=1")
  //add tween at blueGreenSpin label
  .to("#blue", 2, {x:750, rotation:360}, "blueGreenSpin")
  //insert tween 0.5 seconds after blueGreenSpin label
  .to("#orange", 2, {x:750, rotation:360}, "blueGreenSpin+=0.5");
  

Hopefully by now you can see the true power and flexibility of the position parameter. And again, even though these examples focused mostly on to(), it works exactly the same way in from(), fromTo(), staggerFrom(), staggerFromTo(), staggerTo(),add(), call(), and addPause().

Challenge

Now that you've seen what position can do, why not take it for a spin? What better way to learn than to dive head-first into a real-world challenge?

Challenge Brief

Oh no, it seems the developer working on the big project got hit by a bus and he'll be in the hospital for months. Thankfully he was smart enough to start his project using GSAP but he was a bit of a bonehead when it came to using the position parameter. Check out his unfinished work below:

See the Pen Challenge: Position - Start by GreenSock (@GreenSock) on CodePen.

His animation is a bit out of whack and the client has the following demands for you:

  • Man should start animating 1 second before car animation ends.
  • One second after man animation ends both car and lift should go up simultaneously.

For a visual representation of what the finished product should like, here is a .mov and .gif.

Alright it's time to put your animation chops to the test.

Challenge instructions

There are multiple solutions that require only adding the proper position parameters. Some are more flexible than others, but the important part right now is that the end result meets the clients demands.

Need more help getting started?