Jump to content
GreenSock

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

Add the same timeline to multiple other timelines

Recommended Posts

Can 1 timeline, be added to multiple other timelines?

 

I've added 1 timeline, to two different timelines, and only one instance of the added timeline is firing.

 

If not, what is the best workaround for this scenario?

 

Thank you, and thank you for such an amazing product.

Link to post
Share on other sites

A timeline has only one parent, so it can't be part of multiple timelines at the same time. That would be like having the same element appear in more that one place in your page at the same time.

 

If you want the same animation, make another timeline. Use functions to make your timelines so you Don't Repeat Yourself.

 

tl1.add(someAnimation());
tl2.add(someAnimation());

function someAnimation() {
  return new TimelineMax()
    .to(foo, 1, { x: 100 })
    .to(bar, 1, { x: 100 })
    .to(baz, 1, { x: 100 });
}

 

 

  • Like 2
Link to post
Share on other sites

@OSUblake is right, and that's generally the approach I'd take. If you really want to just have one timeline that you're adding to multiple other timelines, there's a tricky way you could do it (but again, this generally isn't the ideal approach): 

 

You can pause that animation and literally control its playhead using other tweens. For example:

var tl = new TimelineMax({paused:true});
tl.to(...); //add all your tweens
...

var parent1 = new TimelineMax();
var parent2 = new TimelineMax();

parent1.add( tl.tweenFromTo(0, tl.duration()), 2); //add it at a time of 2
parent2.add( tl.tweenFromTo(0, tl.duration()), 4); //add it to the other parent at a time of 4

 

All the tweenFromTo() method does is spit back a TweenLite that animates that timeline's "time" accordingly, using a Linear.easeNone ease. 

 

 

So you're creating a tween for each "placement" into another timeline. 

 

Make sense? 

 

Again, I generally prefer Blake's approach. Just wanted to chime in with another answer to your direct question. 

 

  • Like 1
Link to post
Share on other sites

@OSUblake and @GreenSock thank you so much for your help and prompt reply. I really, I really appreciate it.

 

I'm still a nascent coder, and when the environment changes, I loose sight of the basics. 

 

Thank you again! I'm very happy I found GreenSock!

  • Like 2
Link to post
Share on other sites

I'm sorry to bug everyone with this again, but I'm still encountering some issues.

 

I actually have the same module in two different parts of the same page.

 

This is my solution:

function contentsAnimation(){
	return new TimelineMax()
		.from(".contents__label", .4, {opacity:0, y:'+=25'})
		.staggerFrom("li.contents__chapter", 0.2, {opacity:0, x: '-=15'}, 0.15, '-=1.1');
}

var contentsHome_tl = new TimelineLite();
contentsHome_tl
	.add(contentsAnimation());

var contentsChapter_tl = new TimelineLite();
contentsChapter_tl
	.add(contentsAnimation());

var contentsBottom_tl = new TimelineLite();
contentsBottom_tl
	.add(contentsAnimation());

 

I then .add the resulting timelines (contentsHome_tl, contentsChapter_tl, contentsBottom_tl) to different, parent timelines.

 

However, I'm encountering some odd behavior, and I'm assuming I've done something wrong.

 

Any further help you can provide is greatly appreciated. Thank you again.

 

Link to post
Share on other sites

Can you be a little more specific about the "odd behavior" you're encountering? 

 

Please keep in mind that by default, when any tween begins for the first time, it'll look for other conflicting tweens (ones that are trying to control the SAME property of the SAME object) and kill the overlapping/conflicting parts. That's typically a GOOD thing, as it protects you. Otherwise, you might have one tween trying to animate object.x to one value, and another trying to animate it to a completely different value. The way you're doing things looks like you might be creating conflicts. Are you running your timelines concurrently? Again, be careful not to create your animations in such a way that they'll conflict with each other. 

 

If you want to allow the conflicts, you could set overwrite:false on each tween (or TweenLite.defaultOverwrite = false if you want it to affect everything). In most cases I wouldn't really recommend that, though. 

 

Also, I noticed you're using from() tweens. Remember that those animate things to whatever the current value is at the start of the tween, from the value you define. So be very careful about the logic there. For example, if you've got one tween that finishes running, and then another one starts, it'll lock in that current value as the "to". And from() tweens render immediately by default, thus the first time you call contentsAnimation(), it'll actually set opacity:0 and the x/y values as you defined them there, so the NEXT time you call that function, the values will already be rendered in that way. 

 

For example, if obj.x is at 0, and then I call .from(...{x:100}) then obj.x will be 100 IMMEDIATELY and it'll start animating toward 0 on the next render. So if I call from(...{x:100}) again at that point, it'll again make obj.x 100 and use the current value as the "to", but it's already 100 because of your previous from(), thus that second tween will animate obj.x from 100 to 100 (no change). 

 

I bet that might be your problem. Perhaps it'd be wiser to use a fromTo() and staggerFromTo() so that you can control both the from and to values. 

 

If you're still running into trouble, a codepen would be super helpful.

  • Like 2
Link to post
Share on other sites

@GreenSock thank you again for your help and the explanation.

 

Let me try this again using .fromTo() and see if I can fix this before I bug you further.

 

 

Link to post
Share on other sites

@GreenSock I switched to .fromTo() and .staggerFromTo() and I'm still encountering an issue where the elements within contentsAnimation() start at an opacity: 1, then it looks like it repeats the .staggerFromTo().

 

 

See the Pen jGByBx by rgrober (@rgrober) on CodePen

 

Link to post
Share on other sites

Hi @rgrober :)

 

It looks like you're planning ScrollMagic triggers for this, correct? I see ScrollMagic setting tweens, but the ScrollMagic files aren't even loaded so it looks like timelines are firing and overwriting the others and it all seems to animate incorrectly. I forked your pen and loaded the ScrollMagic scripts and it all appears to run correctly to me. Is this what you wanted it to do?

 

See the Pen dVvvYR by PointC (@PointC) on CodePen

Hopefully that helps. Happy tweening.

:)

 

  • Like 1
Link to post
Share on other sites

@PointC thank you so much for having a look!

 

I actually have ScrollMagic loaded on my site, but forgot to include it in my codePen!

 

What's interesting is that it seems to be working in the codePen, but it's not working in my code. I must have duplicated something, or something is out of place in my code.

 

I really, really appreciate your help.

Link to post
Share on other sites

I played with my code, and when I add this line:

 

var controller = new ScrollMagic.Controller();

 

The problem occurs again.

 

I know this is the GreenSock forum, but if anyone has seen this issue occur with ScrollMagic, any information would be greatly appreciated.

 

Link to post
Share on other sites

In addition to ScrollMagic, you are also loading the ScrollMagic GSAP plugin, correct? (also make certain you are loading that plugin after TweenMax)

 

https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/animation.gsap.js

 

That file is necessary for ScrollMagic to take control of the tweens. More info:

http://scrollmagic.io/docs/animation.GSAP.html

 

If that doesn't work, you can also export the CodePen (little button on lower right) and compare it to your local files to find out what's different. I only suggest this as you said it was working on CodePen, but not locally.

 

Hopefully that helps. Happy tweening.

:)

  • Like 1
Link to post
Share on other sites

@PointC, I do indeed have that plugin loaded after TweenMax.

 

All of the other elements that have a ScrollMagic trigger work fine. 

 

It's only this particular instance where the same part of code is being animated, and triggered, twice on the same page.

Link to post
Share on other sites

If it's working correctly in CodePen, but not locally, there has to be some difference. I'd recommend exporting the pen and go through both versions side by side to find out what's different. I'd like to offer more advice, but I can't think of anything else to try right now.

 

Good luck and happy tweening.

:)

Link to post
Share on other sites

@PointC The code doesn't work in either CodePen, or in my code locally, when this line is added:

 

var controller = new ScrollMagic.Controller();

 

Locally, I removed all other code from my javascript file until I found what was causing the issue, and it seems to be the above code. It only seems to affect the instance where I am trying to animate the same div in two different spots on the same page.

Link to post
Share on other sites

I see. I got confused when you said it seemed to be working in CodePen. I now see that the fork I made did not have a ScrollMagic controller.

 

What's happening is your ScrollMagic scenes are triggering and firing all the timelines immediately. To show you what I mean, I've forked your pen and added the indicators with some offsets. (side note: it's always a good idea to use addIndicators while working with ScrollMagic as it can quickly identify problems)

 

See the Pen mBWZGW by PointC (@PointC) on CodePen

 

See how triggers 1&2 are offset so they don't immediately fire? The way you had it before, everything was firing on page load. Now the animation still plays on page load without hitting any triggers. Why? Because you also have that contentsAnimation() timeline nested in your contentsBottom_tl timeline on line 16. The contentsBottom_tl  timeline is not in any ScrollMagic scenes so it fires on page load. Make sense?

 

Hopefully that helps. Happy tweening.

:)

  • Like 3
Link to post
Share on other sites

@PointC I cannot tell you how much I appreciate your help and patience explaining this to me.

 

I'm not sure I would have known where to start to fix this problem, so I'm very thankful for the time you spent to show me the way.

 

Thank you again!

  • Like 3
Link to post
Share on other sites

You're welcome. Happy to help. Good luck with your project. 

:)

  • Like 1
Link to post
Share on other sites

I think I've identified the problem, after implementing indicators and offsets as suggested above.

 

Also, as @PointC mentioned:

Quote

Because you also have that contentsAnimation() timeline nested in your contentsBottom_tl timeline on line 16. The contentsBottom_tl  timeline is not in any ScrollMagic scenes so it fires on page load.

 

So, in my code locally, I included contentsBottom_tl in a ScrollMagic scene.

 

The actual problem seems to be that when I call contentsAnimation() in more than one timeline, it fires contentsAnimation() automatically on page load in all Magic Scroll scenes.

 

This code causes contentsAnimation() to fire automatically on all parts of the page:

function contentsAnimation(){
	return new TimelineLite()
		.fromTo([".contents__label", ".contents__label--green"], .4, {opacity:0, y:'+=25'}, {opacity:1, y:0})
		.staggerFromTo("li.contents__chapter", 0.5, {opacity:0, x: '-=15'}, {opacity:1, x: 0}, 0.15, '-=.5');
}

var contentsHome_tl = new TimelineLite();
contentsHome_tl
	.add(contentsAnimation());

var contentsChapter_tl = new TimelineLite();
contentsChapter_tl
	.add(contentsAnimation());

var contentsBottom_tl = new TimelineLite();
contentsBottom_tl
	.add(contentsAnimation());

 

This code (removing the other timelines that include contentsAnimation()) allows for the first instance of contentsAnimation() to load only when the Trigger is encountered (the behavior I want on another instance of contentsAnimation() lower on the page).:

function contentsAnimation(){
	return new TimelineLite()
		.fromTo([".contents__label", ".contents__label--green"], .4, {opacity:0, y:'+=25'}, {opacity:1, y:0})
		.staggerFromTo("li.contents__chapter", 0.5, {opacity:0, x: '-=15'}, {opacity:1, x: 0}, 0.15, '-=.5');
}

var contentsHome_tl = new TimelineLite();
contentsHome_tl
	.add(contentsAnimation());

 

Is there another way to call contentsAnimation, in other timelines, so it doesn't fire automatically on page load and only fires when a specified trigger is encountered?

 

Thank you again!!!

Link to post
Share on other sites

I'm not following your new question. As I mentioned above, if you add your 'contentsBottom_tl' to a ScrollMagic scene, it won't fire on page load. I've made a quick fork and created a new scene for that other timeline that was firing on page load. You can see that nothing is happening on page load now because all three timelines are under the control of ScrollMagic.

 

See the Pen WZEXrr by PointC (@PointC) on CodePen

If that's not what you meant, a new CodePen would be helpful. 

 

Happy tweening.

:)

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.

×