Jump to content
Search Community

Nested timelines running in parallel

Gary 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 Gary,

 

This simply has to do with "when" you're adding the nested timelines to the parent one.

 

What you're doing is this:

  1. Create the master and nested timelines, and storing them in variables.
  2. Add the nested timelines to the parent.
  3. Adding set() and to() instances to the nested timelines.

What happens is that when you add the nested timelines the duration of both is 0 seconds so they're both added at 0 seconds in the parent one, therefore they play simultaneously.

 

If you add the nested instances to the parent after you add the to() and set() instances to them, it works as you expect:

var outer = new TimelineMax({onUpdate: showProgress, paused: true});
var inner1 = new TimelineMax(), inner2 = new TimelineMax();

inner1.set(foo, {x: 100, y: 100, fontSize: 128});
inner1.to(foo, 4, {rotationZ: 360});

inner2.to(foo, 0.5, {scaleX: 0.5, scaleY: 0.5, repeat: 5, yoyo: true});

outer.add(inner1);
outer.add(inner2);

Rodrigo.

  • Like 1
Link to comment
Share on other sites

Makes sense, thanks.  I was under the impression that because I didn't specifically define an offset for the second timeline, it was +0 relative to the prior sibling completing.

 

In my app, I'm going to have a large tree of timelines and tweens.  It's possible that an arbitrary timeline in the tree will change (e.g. a tween added, removed, duration changed, etc.).  I'd rather not have to rebuild the whole structure to propagate the timing changes. Is there a method I can call, say on my root timeline, that refreshes the start times for the child timelines and tweens configured to start relative to the prior one?

Link to comment
Share on other sites

Hey Gary,

 

You don't need to rebuild the parent timeline, what you can do, and this is a recommendation I always give, is use labels when you're nesting timelines. With a timeline added relative to a label if something changes, everything gets pushed back/forward so you don't have to go through that gruelling process all the time.

var outer = new TimelineMax({onUpdate: showProgress, paused: true});
var inner1 = new TimelineMax(), inner2 = new TimelineMax();

inner1.set(foo, {x: 100, y: 100, fontSize: 128});
inner1.to(foo, 4, {rotationZ: 360});

inner2.to(foo, 0.5, {scaleX: 0.5, scaleY: 0.5, repeat: 5, yoyo: true});

outer.add(inner1, "inner1");
outer.add(inner2, "inner2");

In order to learn how to get the most out of timelines, I recommend you to check this great video Carl made:

 

http://www.greensock.com/sequence-video/

 

Rodrigo.

Link to comment
Share on other sites

I tried updating the codepen I think how you described.  I used labels when adding the timelines.  Later on, I update the first timeline but it didn't push the second timeline out.

 

See the Pen Iquha?editors=001 by GaryC (@GaryC) on CodePen

 

I had seen Carl's video. It's great.  Two things that I think are different than Carl's video is, first, he's making tweens relative, not timelines.  The second, which is probably more relevant, is he is not changing the tree later.  The labels are being used as it is statically built up in code.  

 

I expect my use case is not all that common as most GreenSock users build a static script.

 

Thanks for the advice!

Link to comment
Share on other sites

Hi Gary,

 

I'll start at the end:

 

I expect my use case is not all that common as most GreenSock users build a static script.

 

 

Yeah, this is a pretty accurate statement although some folks like yourself find yourself in a position where you need more flexibility.

 

Let me back up just to clarify a few things

 

  • when tweens and timelines are added to a timeline they are both treated the exact same way. 
  • when you add tweens at a time relative to the end of the timeline (or relative to a label), the relative timing is only applicable at the time of insertion. Any change you make to the duration() or startTime() of child tweens does not push effect the startTime() of other children of the timeline.

 

So what you experienced is exactly how the engine is designed to work. So as you realized, changing the duration of your first timeline is not going to change the startTime() of the second timeline.

 

In your reduced case you could manually move the inner2 timeline by changing its startTime() based on  inner1's new duration()

//A while later a new tween is added to the first inner timeline.  It doesn't appear to push the labels out.
inner1.to(foo, 2, {x: "+=200"});


//adjust the startTime() of inner2
inner2.startTime(inner1.duration());

 

http://codepen.io/GreenSock/pen/buHxt

 

 

 

If you need to move a bunch of  children of your timeline (timelines, tweens, labels) you can use the TimelineLite's shiftChildren() method

 

Shifts the startTime of the timeline's children by a certain amount and optionally adjusts labels too. This can be useful when you want to prepend children or splice them into a certain spot, moving existing ones back to make room for the new ones.

Parameters

  amount:Number — Number of seconds (or frames for frames-based timelines) to move each child.     adjustLabels:Boolean (default = false) — If true, the timing of all labels will be adjusted as well.     ignoreBeforeTime:Number (default = 0) — All children that begin at or after the startAtTime will be affected by the shift (the default is 0, causing all children to be affected). This provides an easy way to splice children into a certain spot on the timeline, pushing only the children after that point back to make room.

 

So if you had 30 timelines in your main timeline you could change the duration() of the first timeline and then grab all the other children and shift them at the same time.

 

Another approach might involve using the getChildren() method to get an array of all the tweens and timelines in a timeline and then you loop through that array and adjust the startTime() of each animation based on the cumulative duration of all previous animations.

 

Hopefully this helps you understand more about things work and what you can do to make your system more flexible. The good news is that you can get a lot of information about each child element of your timeline and adjust the startTime() and duration() how you need, and yes it may not be simple, but there are options.

 

Let us know if you need more help

 

Carl

  • Like 2
Link to comment
Share on other sites

Hi,

 

Thanks for clearing that up Carl, I was rambling around in codepen, scratching my head about this.

 

In order to add into this, IMHO it seems more intuitive for everything to get pushed, in the same way everything gets moved in a single timeline when more instances are added to it before the end. I'm pretty sure though that this works like that for a specific reason, maybe a tradeoff in performance for looking and adjusting everything else up the ladder, when it comes to nested timelines.

 

Rodrigo.

Link to comment
Share on other sites

Thanks for the details.  It looks like there are good options.  I don't mind writing the code to make it work.  I may just punt for awhile and rebuild everything as changes are made, until I can prioritize it.  I'll test your garbage collection code.  :)

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