Jump to content
Search Community

How to invalidate timeline to reflect parameter changes coming from function

RolandSoos test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

In the following example, the x starting point a function which returns the value where should the tween start from. I use function as I have a variable which might change for some events and when this variable changes, I can inform the timeline with the .invalidate() to evaluate the function again for the new value. 

The problem is that when the timeline is paused, this invalidate is not working and the new values are not rendered. The expected behavior for me that the red box is jumping on the X axis when the random number changes. 

 

Using tl.time(0.000001); instead of tl.time(0); solves this issue, but maybe you have a better solution for this case.

See the Pen ExmvGZq?editors=1010 by mm00 (@mm00) on CodePen

Link to comment
Share on other sites

  • Solution

That's because you're not allowing the playhead to hit the spot where that tween is. You're just going from 0 to 0.1 to 0, etc. but the tween starts at a time of 1, thus it never gets tripped. 

 

Remember, GSAP is highly tuned for performance which means animations don't render until they really NEED to. 

 

You can just force it to the end and back again: 

See the Pen Vwbzgyx?editors=0010 by GreenSock (@GreenSock) on CodePen

  • Like 1
Link to comment
Share on other sites

Thank you Jack! 

 

Maybe it would be great to have an option on invalidate method, like:

 

.invalidate({
 immediateRender: true // default is false 
})

When immediateRender would be set to true, GSAP would render all tweens on that timeline at the current playhead (even if that tweens come in the future). 

Link to comment
Share on other sites

6 minutes ago, RolandSoos said:

When immediateRender would be set to true, GSAP would render all tweens on that timeline at the current playhead (even if that tweens come in the future). 

That doesn't quite make sense to me - "all tweens at the current playhead" and "even if that tween comes in the future". If a tween comes in the future, why would it render at that time? Are you suggesting that the timeline would just .progress(1) and then back to the current position? 

 

Please keep in mind that rendering order is absolutely critical in a fully-integrated animation system. Imagine someone sequences multiple tweens that make #box move incrementally, so the first tween makes it go to 100, then the next one goes to 200, etc. If the playhead hasn't reached any of them yet, imagine what would happen if we forced them all to render at a time of 0. How would the later ones even know what value they're supposed to start at if the prior ones haven't rendered at their end state (before they start)? 

 

It's not as simple as "just make them all render immediately". Of course we could force the playhead to the end and back again which would cause everything to render in the proper order but sometimes people don't want their whole timeline to render at the end and lock in all the values the moment they call invalidate(). Of course we could make it an option, but I'm not sure how essential this is to have in the core since it's pretty easy to just do manually and most of the time people don't want it to render immediately. At least I assume that's the case since you're the first person who has ever suggested this :) But of course it wouldn't be terribly difficult to add. I'm just always very protective of file size, so unless there's a very clear and obvious benefit to a good portion of our users, I'm reluctant to add things like this. 

Link to comment
Share on other sites

I see your point. I think there would be an optimized way to make my suggestion work:

When invalidate({...}) called with my option:

  • If playhead is inside a tween -> If start or end value is a function or arithmetic string ("+=100"), initialize the tween again and render its current state
  • If playhead after a tween (tween is at progress === 1)-> If end value is a function or arithmetic string ("+=100"), initialize the tween again and render its current end state
  • If playhead before a tween (tween is at progress === 0)-> If start value is a function or arithmetic string ("+=100"), initialize the tween again and render its current start state

 

Link to comment
Share on other sites

Jack, any suggestion for this case? It is similar to the original. The difference that I invalidate when the playhead is at the end of the timeline and then trying to seek back to the start point. My opinion is that the red box should be at x:600 when the last timeout ends, but it stucks at x:0

 

See the Pen jOmLgRd by mm00 (@mm00) on CodePen

Link to comment
Share on other sites

Again, GSAP is optimized to only render when it MUST, so if a tween has already rendered when its playhead is at a particular spot it won't render again unless its playhead moves elsewhere. Solution in your case: you could rewind to progress 0, jump to 1 and then back to your time:

tl.invalidate().progress(0, true).progress(1, true).time(t, true);

 

7 hours ago, RolandSoos said:
  • If playhead is inside a tween -> If start or end value is a function or arithmetic string ("+=100"), initialize the tween again and render its current state
  • If playhead after a tween (tween is at progress === 1)-> If end value is a function or arithmetic string ("+=100"), initialize the tween again and render its current end state
  • If playhead before a tween (tween is at progress === 0)-> If start value is a function or arithmetic string ("+=100"), initialize the tween again and render its current start state

This would require a lot of extra code and processing if it has to analyze literally every property of every tween. Also, invalidate() is NOT just for function-based values or relative values. It can affect any property. Imagine a simple .to(... {x: 100}) tween where it starts at 0 and it finishes and then you manually reset x to 50 and invalidate(). The next time that tween runs, it'll animate from 50 to 100. In other words, it flushes the recorded starting values. So the logic you proposed wouldn't really work properly. 

Link to comment
Share on other sites

10 minutes ago, GreenSock said:

Again, GSAP is optimized to only render when it MUST, so if a tween has already rendered when its playhead is at a particular spot it won't render again unless its playhead moves elsewhere. Solution in your case: you could rewind to progress 0, jump to 1 and then back to your time:


tl.invalidate().progress(0, true).progress(1, true).time(t, true);

 

Thanks, but I do not see how your logic applies for this example: 

See the Pen jOmLgRd by mm00 (@mm00) on CodePen

 

With this line  tl.invalidate().progress(1, true).time(t, true);we are at the end of the animation as t is equal with the totalDuration of the timeline. 

 

Then we pause and seek back to 0 with the line tl.pause(0). Should I invalidate here again jump to progress(0) and progress(1) and back to progress(0) again?

 

My problem is that the playhead is at the end and then I move the playhead back to the start and GSAP is not redering the changes.

Link to comment
Share on other sites

43 minutes ago, RolandSoos said:

With this line  tl.invalidate().progress(1, true).time(t, true);we are at the end of the animation as t is equal with the totalDuration of the timeline. 

 

Yeah, that's why my last suggestion was to add a .progress(0, true) in there. When I put that into your last demo, it seems to work as expected...right?

 

Again: 

tl.invalidate().progress(0, true).progress(1, true).time(t, true);

 

The order of things depends on the behavior you want. If you .progress(0, true) BEFORE you invalidate(), it'll of course render things back to their starting values before flushing them. Maybe that's what you want. But maybe you altered values NOW that you want those to be the starting values in which case you'd want to call invalidate() before you .progress(0, true). Make sense? 

  • Like 1
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...