Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
tailbreezy

No transition / Instant Snap issue

Recommended Posts

Hello,

 

I am using a master timeline to add two two timelines, one of which has a delayedCall.

The issue is that the ".blue" (e.g the delayedCall) snaps into place without any transition.

 

Why is that and how to fix it?

See the Pen vYGgoJp by dadacoded (@dadacoded) on CodePen

Link to post
Share on other sites

First it's important to note that things work if you don't nest boxesTL in master.

 

Once you nest, the child timeline gets rendered  dependent on where the parent timeline's playhead is.

When your delayedCall() runs, the master timeline is already 1 second ahead into the future which forces boxexTL's playhead one second ahead into the future, thus skipping the part where it animates the blue square.

 

Please see this excerpt from the timeline docs https://greensock.com/docs/v3/GSAP/Timeline

 

When a timeline renders at a particular time, it loops through its children and says "okay, you should render as if your playhead is at __" and if that child is a Timeline with children, it does the same to its children, right on down the line. So the playheads generally remain synchronized.

When you unpause an animation (resume() or play()), it essentially picks up the playhead and moves it so that its internal playhead is synchronized with wherever the parent's playhead is at that moment, thus things play perfectly smoothly. 

 

That is, unless the timeline’s smoothChildTiming is false in which case that child won’t move - its startTime will remain locked to where it was.

So basically when smoothChildTiming is true, the engine will rearrange things on the fly to ensure the playheads line up so that playback feels seamless and smooth. The same thing happens when you reverse() or alter the timeScale, etc. - the animation's startTime shifts automatically. But sometimes you might not want that behavior - that’s when smoothChildTiming: false is handy on a parent timeline.

 

 

  • Like 4
Link to post
Share on other sites

Thank you, Mikel.

 

It is a nice option to know, but in your example the playhead never stops moving as you can see if you add GSDevTools and the CDN link of course.

What I wanted was to actually stop the playhead with a delayedCall, but don't know why it doesn't transition.

 

GSDevTools.create({animation:master})

Link to post
Share on other sites
5 minutes ago, tailbreezy said:

but don't know why it doesn't transition.

 

Take a look at CARL's explanation.

Link to post
Share on other sites

Nope. I can't figure it out even with the tip for smoothChildTiming

An example will be worth a lot at this point

Link to post
Share on other sites

Great idea using GSDevTools! It shows the master is still playing when you call addPause() on the child. the master knows it has 1 more second of animation to play in its child but pausing the child doesn't notify the parent. (pretty sure this is all by design and working correctly)

 

here's a fork with GSDevTools enabled. 

 

See the Pen PoNjEEj by snorkltv (@snorkltv) on CodePen

 

 

smoothChildTiming would go on the master... I tried adding it. I don't think it helps in this context. @greensock or @ZachSaucier or someone else would have to advise on a solution.

 

 

  • Like 1
  • Thanks 1
Link to post
Share on other sites
4 minutes ago, Carl said:

smoothChildTiming would go on the master... I tried adding it

I also tried adding it everywhere :) but didn't seem to work.

From what I gather, as you said and is confirmed by the DevTools the the delayedCall completely pulls out the animation while the master keeps playing.

So the question would be how to stop the master for the same duration. Maybe?

Link to post
Share on other sites

@Visual-Q Excellent. Thank you! 
Indeed a little verbose, but it is a weird request to begin with :)

Link to post
Share on other sites

Updated to make it a bit more flexible:

 

See the Pen YzqQeEe by Visual-Q (@Visual-Q) on CodePen

 

Of course this is when Jack shows up and has a better way.😀

  • Like 1
  • Haha 2
Link to post
Share on other sites

I guess there is no better way after all.

Link to post
Share on other sites

What you're trying to do has some inherent logic issues (unrelated to GSAP) that make it pretty unconventional and fraught with side effects. 

  1. In some of the examples, a callback is being embedded in a child timeline that's reaching out and controlling the playhead of the parent (and the parent is what controls the playhead of the child). Messy logic-wise.
  2. You're pausing a child while the parent's playhead continues...and then when you play() the child again, in order to maintain smooth playback it would have to MOVE that tween's startTime forward by 1 second on the parent timeline so that the playheads are aligned. Doing so likely affects that parent's duration. In your example, the boxesTL is 2-seconds long and it's sequenced after a 1-second timeline, thus the master is 3 seconds long. BUT when you dynamically pause boxesTL at 1 second, by the time you resume it 1 second later, the parent's playhead is at its end (3 second-mark)! So the onComplete could fire, and then when you resume() (assuming smoothChildTiming is true), it'd MOVE boxesTL forward 1 second, making master 4 seconds long now. 
  3. Imagine what'll happen when you restart() master - boxesTL has moved forward 1 second now for that smooth timing, and master is 4 seconds...until that 2nd pause elapses and it stretches the parent to 5 seconds. See the issue(s)?
  4. How would you expect it to play in reverse? GSAP is really built around very tight timing and precise ability to control things in any direction, alter timeScale, etc. This type of dynamic thing really messes with that. 

Usually when I see someone attempting something like this, it's a clue that there's likely a whole different approach that could be taken that'd be much cleaner. It'd help if you could explain the WHY behind what you're doing. Like...what's the practical usage of this? Why would you have a child timeline pause like that rather than just inserting some space in there (between the tweens)? I suspect once we hear your reasoning/goal, we could offer a better approach. 

 

For example, you said "What I wanted was to actually stop the playhead with a delayedCall, but don't know why it doesn't transition." - but can you help us understand why it was important to stop the playhead?

 

All that being said, here's one other alternative - a helper function that you can reuse that'd pause the PARENT:

function pauseParent(child, duration, positionInChild) {
  child.add(function() {
    let time = child.startTime() + this.startTime();
    child.parent.pause(time);
    gsap.delayedCall(duration, () => child.parent.play(time + 0.001, true)); // move the playhead forward slightly so it doesn't call this pause again.
  }, positionInChild);
}

So you'd use it like: 

boxesTL.to('.red',{x:300})
pauseParent(boxesTL, 1); // pause the parent for 1 second
boxesTL.to('.blue',{x:300})

And here's a fork of Carl's CodePen: 

See the Pen wvGqvLz?editors=0010 by GreenSock (@GreenSock) on CodePen

 

I hope that helps a bit. 

  • Like 3
Link to post
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.

×