Jump to content
Search Community

Multiple timelines sharing ".add(.play())" won't play

TartufoDAlba test
Moderator Tag

Go to solution Solved by OSUblake,

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

Hello Gsap'ers,

 

I have attached 2 code pens:

 

1.

As you can see by this pen 3 timelines share the play function ".add(scaleme.play())".

This "should" initiate timeline "scaleme" at the end of their corresponding timeline(s).

I noticed that with a multiple timelines sharing the ".add(scaleme.play())" function it will not play.

 

2. 

See the Pen EmYGYK by tartufodalba (@tartufodalba) on CodePen

As you can see on this one I removed ".add(scaleme.play())" from playme2, playme3.

And then if you click "playme1" (red box) the "scaleme" timeline properly executes.

 

 

Is there anyway to properly implement this so that the timelines in the first codepen each can share that play button?

 

Thank you

See the Pen bWbQmj by tartufodalba (@tartufodalba) on CodePen

Link to comment
Share on other sites

HI TartufoDAlba :)

 

Looks to me like you're dealing with an overwrite situation. You're trying to add the same timeline to 3 parents so the third one overwrites the other two. That's why your first demo works correctly if you hit button 3. 

 

The easiest thing to do would be putting that scaleme timeline into a function and call it onComplete from the other timelines.

 

Hopefully that helps.

 

Happy tweening.

:)

  • Like 1
Link to comment
Share on other sites

HI TartufoDAlba  :)

 

Looks to me like you're dealing with an overwrite situation. You're trying to add the same timeline to 3 parents so the third one overwrites the other two. That's why your first demo works correctly if you hit button 3. 

 

The easiest thing to do would be putting that scaleme timeline into a function and call it onComplete from the other timelines.

 

Hopefully that helps.

 

Happy tweening.

:)

 

Yes I see what you mean thanks.

 

What if per-say I wanted to call/play "scalme" in the middle of the 3 other timelines?

(where I don't believe onComplete would work since it would no longer be just on completion)

Link to comment
Share on other sites

You can add the function that plays the 'scaleme' timeline to any of the other timelines. You just can't have the actual timeline existing on three parents at the same time. Say you wrap your 'scaleme' timeline in a function like this:

function scaleMe() {
var tl = new TimelineMax();
tl.to(".scale-me", 0.2, {scale: 1.5});
return tl;
}

You can then add that function call to any of the other three timelines at any position like this:

playme1.to(".box-1", 0.2, {autoAlpha: 0.5, scale: 1.1});
playme1.add(scaleMe); // no parentheses or the function will execute immediately

Does that make sense?

 

Happy tweening.

:)

Link to comment
Share on other sites

  • Solution

Looks like there is a lot of confusion going on here. Like PointC said, a child can only belong to one parent. Made a similar post yesterday about that.

https://greensock.com/forums/topic/16333-re-run-tween-in-a-timeline-at-a-later-point-in-the-timeline/?p=71900

 

But I think the bigger issue here is understanding .add() and how stuff evaluates.

 

Using .add(), you can add a tween, timeline, callback, or label. So what are you adding here?

playMe.add(scaleMe.play())

If you said a callback/function, you're wrong. You're adding the scaleMe timeline to the playMe timeline. You're calling .play(), and if you look in the docs, you'll see that it returns itself, which would be the timeline.

 

 

 

To call play as callback, you would need to do one of these...

// Bound callback
playMe.add(scaleMe.play.bind(scaleMe));

// Add callback
playMe.addCallback(scaleMe.play, "+=0", [], scaleMe);

// Callback
playMe.add(function() {
  scaleMe.play();
});

Let's look at how some other things evaluate.

 

What is this?

playMe.add(noop);

function noop() {}

That's a callback.

 

 

 

Then what is this?

playMe.add(noop())

function noop() {}

That will result in an error. By default, every function in JavaScript returns undefined when it's called. That lets the JavaScript engine know when the function is done running. The reason for the error is because it's returning undefined, and you can't add undefined to a timeline.

 

 

 

So what's this?

playMe.add(createTween())

function createTween() {
  TweenLite.to("#foo", 1, { x: 100 });
}

Another error. It's returning undefined.

 

 

 

 

What about now?

playMe.add(createTween())

function createTween() {
  return TweenLite.to("#foo", 1, { x: 100 });
}

That's a tween, which will be added to the timeline.

 

 

 

 

What about now?

playMe.add(createTween)

function createTween() {
  return TweenLite.to("#foo", 1, { x: 100 });
}

That's a callback, which will create a tween that will run independently from the timeline. Returning something in callback will have no effect, it's void.

 

 

 

 

What's going to happen here?

playMe
  .add(createTween1)
  .add(createTween2())

function createTween1() {
  return TweenLite.to("#foo", 1, { x: 100 });
}

function createTween2() {
  return TweenLite.to("#bar", 1, { x: 100 });
}

If the timeline is empty, both tweens will start playing at the same time. The second tween is the only one that will be part of the timeline. The first tween is created inside a callback.

 

 

 

So what's going to happen here?

playMe
  .add(createTween1())
  .add(createTween2())

function createTween1() {
  return TweenLite.to("#foo", 1, { x: 100 });
}

function createTween2() {
  return TweenLite.to("#bar", 1, { x: 100 });
}

The tweens will play sequentially, and both tweens will be part of the timeline.

 

 

.

  • Like 5
Link to comment
Share on other sites

Whooooops - yeah I dropped the ball on my answer with my not using parentheses goof.  :rolleyes:

 

I think I was typing add(), but still had onComplete on the brain after my first answer. My apologies for any additional confusion I created.  If I need to turn in my Moderator badge to Carl, just let me know. 

 

Great info Blake. 

:)

  • Like 2
Link to comment
Share on other sites

Hello TartufoDAlba,

 

To add to all the great advice that has been posted in this topic...

 

In my opinion, the GSAP add() method is best used when your adding child timelines to a parent timeline.

 

Carl shared that great tip with me, a long time ago in a galaxy far far away. That would be one of the easiest tips to remember about using the GSAP add() method.

 

Then by creating those child timelines they can be reused or added to other master timelines, or when needed in any event handlers.

// create master timeline in a paused state
var masterTL = new TimelineMax({paused:true});

// create 1st child timeline
function timeline1() {
    var tl = new TimelineMax();
    tl.to("#foo", 1, { x: 100 });
    return tl;    
}

// create 2nd child timeline
function timeline2() {
    var tl = new TimelineMax();
    tl.to("#bar", 1, { y: 100 });
    return tl;
}

masterTL
.add(timeline1()) // add child timeline1 to master timeline
.add(timeline2()) // add child timeline2 to master timeline
.play();

Again you don't have to create your animations this way, but it is recommended to simplify the creation of various child timelines and will give you full control when you add them to your master timeline or in any event handlers you setup.

 

Just to add my two cents :)

 

Resources:
GSAP add(): https://greensock.com/docs/#/HTML5/GSAP/TimelineMax/add/

  • Like 4
Link to comment
Share on other sites

The main thing about this project is it is not using a single master timeline.

 

It is basically a "choose your own adventure" with multiple timelines. Where different timelines end up sharing partial elements and can each end up at the same location. This is why I had them separated and not into a single master timeline.

 

I appreciate all the input and will be going through each post step by step. Thank you!

Link to comment
Share on other sites

Hello TartufoDAlba,

 

To add to all the great advice that has been posted in this topic...

 

In my opinion, the GSAP add() method is best used when your adding child timelines to a parent timeline.

 

Carl shared that great tip, a long time ago in a galaxy far far away. That would be one of the easiest tips to remember about using the GSAP add() method.

 

Then by creating those child timelines they can be reused or added to other master timelines, or when needed in any event handlers.

// create master timeline in a paused state
var masterTL = new TimelineMax({paused:true});

// create 1st child timeline
function timeline1() {
    var tl = new TimelineMax();
    tl.to("#foo", 1, { x: 100 });
    return tl;    
}

// create 2nd child timeline
function timeline2() {
    var tl = new TimelineMax();
    tl.to("#bar", 1, { y: 100 });
    return tl;
}

masterTL
.add(timeline1()) // add child timeline1 to master timeline
.add(timeline2()) // add child timeline2 to master timeline
.play();

Again you don't have to create your animations this way, but it is recommended to simplify the creation of various child timelines and will give you full control when you add them to your master timeline or in any event handlers you setup.

 

Just to add my two cents :)

 

Resources:

GSAP add(): https://greensock.com/docs/#/HTML5/GSAP/TimelineMax/add/

 

I would also mark this thread solved with this answer also if I could. Thank you for the input. It is great that you can keep the code clean and re-use areas instead of copying and pasting the same thing over and over.

  • Like 2
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...