Jump to content
Search Community

Nested timeline remove pause automatically when nested

RolandSoos 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

I have an async use-case when the nesting of the timeline is event based. So I can not be sure that when the secondary timeline will be added in the future to the main timeline as it is based on an event. Also, the secondary timeline might be reused several times.

 

Simulation:

  • Click on "Create timeline"
  • Click on "Add nested timeline"
  • Click on "Play"

 

Expected final behavior:

Secondary timeline {pausedtrue} and when I add this timeline to the main timeline, I need to remove the paused state:

See the Pen PBYzNP?editors=1010 by anon (@anon) on CodePen

 

Fails:

Secondary timeline {pausedtrue} and paused state not removed:

See the Pen yqBJez?editors=1010 by anon (@anon) on CodePen

 

Secondary timeline not paused:

See the Pen JBPKPm?editors=1010 by anon (@anon) on CodePen

 

I know why the codepens listed in fails, why does not work. And they just work fine, it is not a bug in GSAP.

 

The question: Is there a way to reach a solution when the secondary timeline is paused by default and only plays when it's nested?

 

Link to comment
Share on other sites

Interesting question...

 

I assume you are aware of much what I am about to write, I'm just 'writing it out loud' as it helps me think..

 

You know that you can add a nested timeline that will only play when the parent timeline 'cursor' gets there without having to set it's property to true.

 

However you want to create a timeline, wait for an async response in the future then add it to the parent. May I ask you why? Why must you create the timeline before the async response? Creating timelines is generally so cheap you could just wait for the response before creating and adding the nested timeline.

 

You also say the secondary timeline may be reused several times. Well, that begs another question. Are you saying you want the same timeline nested into different timelines? And somehow it knows if it's been played in any of the parents? Or do you want the same type of animation created after a certain event has occurred? For the second option, returning a timeline from a function will do the trick.

 

See the Pen jpNMzJ?editors=0010 by dipscom (@dipscom) on CodePen

 

  • Like 4
Link to comment
Share on other sites

Thanks for providing all the clear demos.

 

Without knowing more of the requirements I would agree with Dipscom's solution of using a function to return a timeline on demand.

What he is referring to as the 'cursor' we typically call the playhead (if that helps clear things up at all).

 

The engine won't automatically unpause a child that you explicitly tell to be paused as that could really confuse people.

"wait, I told this timeline to be paused, why is it now playing?"

 

 

I guess I'm not understanding why the first example you provided (where you unpause it when you add it) is not suitable.

 

 

After some thought and tinkering it seems you could place a callback at the same time as your paused timeline is inserted and use it to unpause that nested timeline.

 

Not sure if that's really the best solution, as there will an imperceptible delay (of a few MS) between when the function is called and when it executes, but it might be an option for you


 

document.getElementById("add").addEventListener("click", function() {
  mainTl.call(unPauseATimeline, [secondaryTL]);
  mainTl.add(secondaryTL)
});



function unPauseATimeline(timeline){
  timeline.play();
}

 

 

See the Pen djbRRB?editors=0011 by anon (@anon) on CodePen

 

  • Like 3
Link to comment
Share on other sites

You can always use promises for complicated async behaviors. Async/await works in all modern browsers, and there are plenty of polyfills for older browsers,

 

button.addEventListener("click", async () => {

  await new Promise(resolve => animateAsync(resolve));
  
  // Starts halfway through the first animation
  animateSync();  
});

function animateAsync(resolve) {
    
  var tl = new TimelineMax({
      delay: Math.random()
    })
    .to(elementA, 2, { x: 500 })
    .add(resolve, 1);
}

function animateSync() {
  
  TweenLite.to(elementB, 1, { x: 500 });
}

 

 

See the Pen PBoYmX by osublake (@osublake) on CodePen

 

  • Like 4
Link to comment
Share on other sites

Thanks for the feedback. Probably I will use the paused timeline and remove the paused state after adding them to the timeline.

 

More details about my case: I try to reuse my compiled timelines as much as I can. I'm working on an editor when each timeline can be played one by one to see the previews. Also, these can be played in linear timelines to see how they look when everything playing. But, on the frontend, these are not linear timelines -> every timeline based on an event. It can be mouse enter/leave/click or a previous animation state (loop completed, out completed) and such).

 

Most animations are linear on this example, but the zeppelin on the left side starts on click:

https://smartslider3.com/city/

image.png

 

Ps.: The image upload in the forum gives an error (There was a problem processing the uploaded file. -200), but the uploaded file seems ok.

 

 

image.png

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