Jump to content
Search Community

Multiple timeline issue

rothgar test
Moderator Tag

Recommended Posts

I'm trying to make a single page with different timelines on it. I want buttons that reset all the other timelines and then play just the one. This is a very simple example of 2 timelines and 2 buttons. If you click tl2 the animation plays but tl1 doesn't do anything. The animation is just a very simple example and my actual animations are much more complex.

 

Looking for some help on why the buttons don't do what I would expect (play the timeline on click and reset other timelines) and if there's a cleaner/better way to set this up when I have more timelines (5+) on a single page I would like to do the same thing.

 

Thank you

See the Pen GRoNRdo by justingarrison (@justingarrison) on CodePen

Link to comment
Share on other sites

You just need to be careful with from() tweens because there are logic issues that can bite you if you don't understand how things work... 

 

A from() tween has immediateRender: true set by default, meaning it'll IMMEDIATELY set things to their starting state. That's a good thing. And to() tweens don't. That's also a good thing. It's utterly pointless to render a to() tween right away because there's no value change. And GSAP is hyper optimized for speed. For example, if you're animating x to 100 (and it's 0 now), when the tween gets created and it's at the very start (time of 0), why render that? It's already at the starting value. Waste of CPU cycles. So a to() tween renders for the first time when the playhead actually moves (on the next tick in most cases). 

 

Now let's look at your code: 

tl1.to(".circle", {x:640, repeat:-1, repeatDelay:0.5});
tl2.from(".circle", {x:640, repeat:-1, repeatDelay:0.5});

The from() tween will force the circle's "x" to be 640 RIGHT NOW. Cool. But if you tl1.play(), on the very next tick that tween will render for the first time and record the start/end values internally. So it says "okay, we're animating x to 640 from whatever it is right now....and it's 640..." (because of the from() tween), so you're animating x from 640 to 640 (no change). That makes it appear broken, but it's not. It's a logic issue in your code. See what I mean? 

 

You have several options:

  • Use fromTo() tweens so that you can control the start and end values. 
  • -OR- force the values to get recorded immediately in your tweens by either setting immediateRender: true or (I prefer this:) just create your timeline and then timeline.progress(1).progress(0). That just forces the playhead to the end and back again which makes the tweens do their first render and record the start/end values internally. So you'd do one timeline, THEN the other, etc. You still need to be mindful of what you're doing to the values. like after the from() call it's gonna force x to 640, so if you don't want your to() tweens to start at 640, make your adjustments accordingly. 
  • -OR- set immediateRender: false on your from() tween. BE CAREFUL: you're still telling it to use the current value for one side (start for from() tweens, end for to() tweens). So if you start playing tl1 and then halfway through you play tl2, it's gonna use that CURRENT value (the halfway-between one). Again, this isn't a GSAP bug. It's the nature of the beast. It's a logic thing.

Does that clear things up?

  • Like 3
Link to comment
Share on other sites

Thank you for the thorough explanation. That is very helpful and I was able to confirm with your examples what I was seeing.

 

Can you help me understand the difference between timeline.progress(0) and timeline.time(0)?

 

Is there a safe way to not have multiple timelines interfere with objects on the page? Would putting the timelines in functions and then setting timeline.progress(0) be sufficient to reset objects to the state when the page loaded?

Link to comment
Share on other sites

3 minutes ago, rothgar said:

Can you help me understand the difference between timeline.progress(0) and timeline.time(0)?

 

In terms of the result, no difference whatsoever. progress() is just a simple way to plug in a value between 0 and 1 where 1 is the very end. Like if you don't know the duration. time() lets you feed in a specific time (in seconds). That's all. Both move the playhead. Use whichever feels more natural for you. 

 

5 minutes ago, rothgar said:

Is there a safe way to not have multiple timelines interfere with objects on the page? Would putting the timelines in functions and then setting timeline.progress(0) be sufficient to reset objects to the state when the page loaded?

I'm pretty sure the same solutions I offered above apply. :) 

 

You could build all your animations as timelines and ensure that immediateRender is false (so that things aren't put in their starting state). Thereafter you could animation.render(-0.01) or something in order to render the animations in their pre-zero state. Technically the playhead cannot go backward past 0 or forward past the very end of the animation, but calling render() and passing in a negative number basically tells it to assign the initial values.

 

Or just use fromTo() animations. That way you get total control over both ends (starting and ending). Does that answer your question?

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...