Jump to content
Search Community

Stagger with custom ending time

RenanSantos 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

Hi Renan. Welcome to the GreenSock forums.


If I understand you correctly, you can accomplish that task by putting each set of staggered animation into its own TimelineMax and then you can set the the duration() of each timeline to be the same. 




//assume elments has 10 items
stagger1 = new TimelineMax();
stagger1.staggerTo(elements, 1, {left:200})

//assume otherElements has 50 items
stagger2 = new TimelineMax();
stagger2.staggerTo(otherElements, 1, {left:200})

//give each timeline a duration() of 2 seconds

//or you can dynamically make the second timeline the same duration as the first

let me know if that gets you in the right direction or if you need more info

Link to comment
Share on other sites

Thanks Carl! :)

I tested changing the duration but the only thing that changed was the TimeScale.


I've got the following result:

tl.duration(); // 1.8


tl.duration(); // 1.8


It works when i play it or change the .progress(), but the animation seems unchanged when using seek() or time().

Link to comment
Share on other sites

Yeah, I should have mentioned that duration() just changes the timeScale accordingly. It doesn't physically crunch or expand the duration of your tweens, their delays or any of that.


And yes, seek() and time() refer to absolute points in the timeline but progress is relative so after adjusting the timeScale, progress(.5) is always going to be the middle of the timeline, but time(2) is always going to be 2 seconds into the timeline regardless of whether or not the duration is now 10 seconds or 20 seconds based on the timeScale being changed. 


I don't know what an easy fix for this is. I think you will have to build your timelines or staggerTo()'s knowing what the duration needs to be and then use some math to figure out the duration and offset of each tween so that they all fit into that time requirement. 


I'll kick this up the brain chain and see if there are any other ways.



Link to comment
Share on other sites

Hey Renan,


That nesting trick is a great solution. Very clever. 

As for the reason why changing the duration() works that way, the duration of a timeline is dictated by the duration of the elements it contains. I imagine there isn't a practical way to recursively loop through every time-based parameter of every nested, tween, timeline and callback and adjust them. 


If I can get you a better answer I will.



Link to comment
Share on other sites

Yep, there are several reasons that altering the duration of a timeline affects its timeScale:

  1. The duration of a timeline is simply the aggregate total of whatever its children are. If we change all of the children's duration accordingly, it would change all of the startTimes inside as well as the label and callback placements. That could get confusing for developers. And what if you set the duration to 10 and then add a tween - should it recalculate everything to fit inside 10 still or would the duration change? Tweens are easy - you set the duration and it's absolute, but timelines are just containers.
  2. Looping through all the children and calculating new durations and placements for them based on a new duration of the timeline would be MUCH less performative than simply changing the timeScale. 
  3. It could be counter-intuitive in several other says, like you could say "I asked to change the duration of the timeline, not all the children - why is my 2-second tween now 1.26731 seconds??" 
  4. What happens to nested children of nested timelines? So if I change the parent's duration and then the grandparent's duration, would it need to loop through and calculate new durations and startTimes for everything nested inside the nested animations?

Think of it like nested divs. If you set the "left" property of a div to 100, and do the same to its child, the child would technically look like its left is 200, but if you check the property itself, it's still only 100. Same with scale, rotation, etc. This is a pretty standard way of handling nested transformations I think. But I can totally see why you might think it's counter-intuitive at first. 


Glad you figured out a solution. Let us know if you need anything else. 

Link to comment
Share on other sites

Here's what the docs say currently: 



Due to the fact that a timeline's duration is dictated by its contents, using this method as a setter will simply cause the timeScale to be adjusted to fit the current contents into the specified duration. For example, if there are 20-seconds worth of tweens in the timeline and you do myTimeline.duration(10), the timeScale would be changed to 2. If you checked the duration again immediately after that, it would still return 20 because technically that is how long all the child tweens/timelines are but upon playback the speed would be doubled because of the timeScale.


How would you recommend making it more clear that the duration remains the same but the timeScale changes? We definitely want to make sure the docs are clear, so any suggestions are welcome. 

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