Jump to content
GreenSock

bfred.it

Interacting with labels in nested timelines

Recommended Posts

I liked the pattern of the code you used for the intro animation on greensocks.com, so I'm trying to use it.

 

You have a main timeline and multiple nested timelines added at a certain offset. I did the same thing, except I'd like to add a timeline at a specific label, rather than a time offset.

 

I'm using this code:

var main = new TimelineLite();
main.add(timelineA());
main.add(timelineB(),'labelFromTimelineA');


function timelineA () {
 var tl = new TimelineLite();
    tl.to('#redBox', 1, {x:100});
    tl.addLabel('labelFromTimelineA');
    tl.to('#redBox', 1, {x:0});
    return tl;
}
function timelineB () {
    var tl = new TimelineLite();
    tl.to('#blueBox', 1, {x:100});
    tl.to('#blueBox', 1, {x:0});
    return tl;
}

 

I noticed that the two nested timelines are effectively merged into the main one (main.getChildren() lists the children of all the timelines) but the labels are not, thus I can't add timelineB at labelFromTimelineA.

 

Is there any simple way to do this?

 

Here I set up a simple pen: 

See the Pen fGorg?editors=001 by bfred-it (@bfred-it) on CodePen

Link to comment
Share on other sites

Thanks SOOO much for the CodePen demo. Huge help... and very clear.

 

Is there any simple way to do this?

 

 

Truthfully, to my knowledge, not really, but it is possible.

 

var main = new TimelineLite();
//we'll offset the startTime of the first timeline
main.add(timelineA(), 1);


//there is no way to reference timelineA directly since it is created in the local scope of timelineA() function, so we'll use getChildren()[0] which finds the first nested timeline
var firstTimeline = main.getChildren()[0]
//now we will dynamically find the startTime();
var timelineAStartTime = firstTimeline.startTime();
//find the time of the label
var timelineALabelTime = firstTimeline.getLabelTime("labelFromTimelineA");
//check our work:)
console.log(timelineAStartTime, timelineALabelTime)
//add the offset startTime() to the labelTime
var insertTime = timelineAStartTime + timelineALabelTime;


main.add(timelineB(), insertTime);


function timelineA () {
 var tl = new TimelineLite();
    tl.to('#redBox', 1, {x:100});
    tl.addLabel('labelFromTimelineA');
    tl.to('#redBox', 1, {x:0});
    return tl;
}
function timelineB () {
    var tl = new TimelineLite();
    tl.to('#blueBox', 1, {x:100});
    tl.to('#blueBox', 1, {x:0});
    return tl;
}

http://codepen.io/GreenSock/pen/apvoE?editors=001

 

To be clear, the reason as you suspected, is because the label in the timeline created by timelineA() lives in THAT timeline, not the main timeline. When you add() something to a timeline at a label, the engine does not recursively search through all nested child timelines for a matching label (although a function that does that could be written).

 

My example above simply looks in the first child timeline for a matching label and figures out what time it relates to in the main timeline.

 

Perhaps the info above will help you get towards a more flexible solution.

  • Like 1
Link to comment
Share on other sites

Hello bfred,

 

You could replace this line:

main.add(timelineB(),'labelFromTimelineA');

With:

main.add(timelineB(),'labelFromTimelineA-=1');

You can also use  

console.log(tl._totalDuration) 

to figure at which point in the time you should add your B animation

Link to comment
Share on other sites

Here's a function that'll do all the hard work for you and even factor in the various timeScales:

function findLabelTime(timeline, label) {
  var time = timeline.getLabelTime(label),
      i = 0,
      children, tl;
  if (time !== -1) { //if the label is in the main timeline, just return the time (performance optimization)
    return time;
  }
  children = timeline.getChildren(true, false, true); //if the label wasn't found, we need to seach all the child timelines.
  while (time === -1 && i < children.length) {
    tl = children[i];
    time = tl.getLabelTime(label);
    i++;
  }
  if (time === -1) { //the label doesn't exist
    return -1;
  }
  time = tl.startTime() + time / tl.timeScale();
  tl = tl.timeline;
  while (tl && tl !== timeline) {
    time = tl.startTime() + time / tl.timeScale();
    tl = tl.timeline;
  }
  return time;
}

And here's the forked codepen:

http://codepen.io/GreenSock/pen/2d5986159030829fd9016a57f028d4e5/

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Wow, excellent! Thank you for taking the time to code that! I really appreciate it  :lol:  

Link to comment
Share on other sites

  • 3 years later...

Just a side note, the above code doesn't seem to work with multiple levels nested timelines.

Link to comment
Share on other sites

@multivac would you happen to have a reduced test case that shows it not working? That'd be super helpful. Maybe a 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.
×