Jump to content
Search Community

TimelineMax progress drifting even when its stopped.

thunderkid test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I'm trying to build a system from your slider animation example. I'm getting performance problems where onUpdate keeps being called even when the timeline isn't supposed to be running.

To see this most clearly, I just took your example and added a display of the timeline's progress. Move the slider anywhere except the leftmost position then let it go. The progress keeps drifting:



It seems that the timeScale is set to 1e-10 instead of zero.

Is there a way around this? Thanks.

See the Pen YyPjJW by thunderkid (@thunderkid) on CodePen

Link to comment
Share on other sites

Ok, so one hackish fix is to check progress for not much change in onUpdate, and set it back to its prev value if the change is very small:

See the Pen meyGVM by thunderkid (@thunderkid) on CodePen

Damn ugly though. Don't know if it would break other stuff in a more complex scenario.

Seems that if you have sub-timelines you'd need to put this same hack into each of their onUpdate's.

Link to comment
Share on other sites

timeScale should never be set to zero because:

  1. It's much more performant to just pause(). 
  2. Internally, the timing calculations involve dividing by the timeScale but you cannot divide a number by zero That's why we limit things to 1e-10. Sure, we could put conditional logic in place to sense when it's zero and work around that, but it's in such a hyper-sensitive area performance-wise that I don't think it's wise. In other words, everybody would pay a price performance-wise just to accommodate an incredibly uncommon edge case that's easily solved by just pausing instead of setting timeScale to zero. 

Is there a reason you can't just pause() instead of setting timeScale to zero? 

  • Like 3
Link to comment
Share on other sites

I see. Actually I just ended up using timeScale(0) because I started off by building on top of your own fine example ;). I assumed timeScale(0) must be the same as pausing. Although the effect of starting/stopping gradually is nice, it's not one I particularly need, so I'll just re-implement using pause/play/resume. But given this difference, shouldn't your example actually pause once the animation to timeScale(0) has finished? Something like this:


See the Pen epmxay by thunderkid (@thunderkid) on CodePen


It still needs one 1e-8 hack, but seems more robust than before.


In general, though, couldn't you just perform a check that whenever timeScale(x) is called internally, if (x<1e-9) pause the timeline, and set a flag saying that it's been paused just for rounding reasons. Seems timeScale(x) would be called only infrequently, so I don't see how it would entail a performance hit. (I haven't actually delved into the code, so this is just random speculation.)

Link to comment
Share on other sites

I didn't want to automatically (internally) pause() when timeScale() is set to zero because:

  1. It could confuse/frustrate users, especially if they have conditional logic in their own code that depends on the paused state of the tween/timeline. Like "hey wait, I never paused the timeline! Why is it paused now?"
  2. It could lead to more confusion when they then set timeScale() to a non-zero number...should that force it to resume()? What if they manually paused it previously, then they change the timeScale() but don't intend for it to start playing yet? See how messy it could get? 
  3. What if they tween timeScale() down to zero so that when it eventually hits zero it automatically pauses but then later they resume()...what would the timeScale() be? 1e-10? If so, they may think "why aren't things animating??? I just resumed!" (it is animating, just REALLY slowly). The alternative would be to then force timeScale back to 1 upon resume() but that could cause all sort of confusion/frustration too ("wait, I intentionally set timeScale() really low, paused, then later resumed...why is my timeScale altered back to 1 now?"

I think this might be a cleaner solution in your codepen:


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...