Jump to content
Search Community

Pause nested timeline created from function call

Dipscom 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

We all know using functions to generate timelines is the way to go but sometimes I find myself needing to stop halfway inside the child timeline but without creating a master timeline scrubber.

 

But for the life of me, I can't pause the nested animation. I can fake it by adding a .call() in the child to pause the master but I assumed if I paused the child, the master timeline would stop as well. But it does not seem the case. Is that expected behaviour?

 

See the attached pen for a super-duper simple example.

 

Ta.

See the Pen a36e23fa0e0be18950044acad6e43f3b by dipscom (@dipscom) on CodePen

  • Like 1
Link to comment
Share on other sites

Children don't tell their parents what to do... at least well behaved children don't.

 

Think about elements. A child element cannot change the position of its parent, and it cannot stop its parent's position from changing.

 

So you would need to do to do something like this. Not pretty, but when you see repetition, that usually means you can use a loop to simplify things.

 

var master = new TimelineLite()
  .add(fadeIn(".d1"))
  .addPause()
  .add(fadeOut(".d1"))
  .add(fadeIn(".d2"))
  .addPause()
  .add(fadeOut(".d2"))
  .add(fadeIn(".d3"))
  .addPause()
  .add(fadeOut(".d3"))

function fadeIn(el) {
  return new TimelineLite().from(el, 0.5, {xPercent:-50, autoAlpha:0})
}

function fadeOut(el) {
  return new TimelineLite().to(el, 0.5, {xPercent:50, autoAlpha:0}, "+=0.2")
}

 

 

  • Like 3
  • Haha 2
Link to comment
Share on other sites

Thanks for the demo with your question.

Blake beat me to the punch with those pesky children trying to control their parents.

 

Like Blake said, the paused state of a child animation does not affect the paused state of its parent. Pausing the parent will always pause the children. The position of the parent’s playhead dictates what is rendered in all child animations. This is a very purposeful design rule that dictates how the entire engine performs. 

 

Stepping back a bit, consider that GSAP has a root timeline that all animations belong to. When you create even a simple TweenLite tween it is added to this root timeline

 

var t = TweenLite.to("body", 1, {rotation:1})
console.log(t.timeline); // logs out a timeline

 

 

It is very good that pausing t does not pause the root timeline thus making every animation pause. Of course Jack could write code that made it so that the root timeline doesn’t get paused in this case, but its good to have consistent behavior throughout. I can understand in your situation how you would like pausing the child to pause the parent, but I think in the grand scheme of things the current design makes the most sense in the most common use-cases.

 

Imagine if pausing the parent did not make the children stop playing? you would have to identify every child tween and pause it (I know you’re not suggesting that).

 

That probably doesn’t give the most clear or accurate explanation of why pausing the child doesn’t pause the parent, but hopefully you trust me that it works that way for good reason and maybe Jack can find the obvious thing I’m not remembering;)


As for your demo, its an interesting scenario. The timeline that is created inside your function has no idea what timeline it is being put inside of after it gets created and returned so there is no great way to write code in there that says “pause my parent”. Your current solution of using call() to call a function that pauses the parent is probably the best thing there is but it isn’t entirely accurate as some minuscule amount of time will elapse while the function is being called and code is being executed. So the pause will not happen at the exact same time your call() happens. A few milliseconds of time drift probably won’t impact what you’re doing but figured I’d mention it anyway. This is the very reason we created a specific addPause() function so that it would ensure the timeline gets paused exactly when it should. Prior to addPause() folks were writing there own calls() to pause the timeline.

 

For pausing the parent with call(), the only slight enhancement I can offer is dynamically finding the parent of the timeline that the call() is in like:

console.clear();
function fadeInOut(el) {
    var tl = new TimelineLite({id:"child"});
    tl.from(el, 0.5, {xPercent:-50, autoAlpha:0})
    tl.call(pauseMyParent);
    tl.to(el, 0.5, {xPercent:50, autoAlpha:0}, '+=0.2');
    return tl;
}

var master = new TimelineLite({id:"master"})
master.add(fadeInOut('.d1'))
master.add(fadeInOut('.d2'))
master.add(fadeInOut('.d3'))
function pauseMyParent() {
  console.log(this.timeline.vars.id);
  console.log(this.timeline.timeline.vars.id)
  this.timeline.timeline.pause();
}
$("#resume").click(function(){
  master.resume();
})


See the Pen vJjwWp?editors=1111 by hansel234 (@hansel234) on CodePen


Maybe that helps a little. Don’t know. There will still be some slight time-drift. 

  • Like 4
Link to comment
Share on other sites

  • 2 years later...

Hey everyone,

 

Sorry to bring this thread back from the dead all these years later. I got stuck for four hours tonight before realizing that a bug I had in a paused timeline was caused by the parent continuing to tick away while the child was paused.

 

Is there a process for proposing changes to the Greensock documentation? I'd love to see this parent/child behavior mentioned on the timeline pause() method page.

 

Thanks all!

Link to comment
Share on other sites

Hey @Tyler Smith and welcome to the GreenSock forums. Making a post in the forums is a great way to get us to affect the docs :) 

 

Can you please create a minimal demo that shows what you're talking about? That'd be helpful for us to see specifically what case we should address.

 

Additionally if you wanted to take a shot at how you would describe it, that would be helpful for us to know what sort of thing you're looking for. Sometimes it's hard for us to phrase things in a way that sense to people who aren't as intimately familiar with GSAP as we are :) 

Link to comment
Share on other sites

@ZachSaucier thank you for getting back to me!

 

I've created a minimal demo here. If you pause and resume the child timeline, you can see a big jump because the parent is still calculating the child's position.

See the Pen VwavGEK by tylerlwsmith (@tylerlwsmith) on CodePen

 

Below is a first pass at language describing this behavior–I'd love to see something like this mentioned on the timeline pause() method page.

 

"When a timeline is nested within another timeline, the parent timeline will continue to calculate the animations of the child timeline, even if the child is paused."

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