Jump to content
Search Community

Playing Nested Timeline More Than Once

CantinaDan test
Moderator Tag

Recommended Posts

When you say "timeline", do you mean a TimelineLite/Max or a MovieClip timeline?

 

TweenLite/Max/TimelineLite/Max instances are like DisplayObjects in the sense that they cannot exist in two places simultaneously. Like if you do parent1.addChild(child) and parent2.addChild(child), child will no longer be in parent1. So you can't add a tween or timeline to a bunch of places in a TimelineLite/Max.

 

You CAN, however, achieve the same effect by pausing the tween (or timeline) and simply create other tweens OF THAT TWEEN's currentTime property, like:

var baseTween:TweenLite = new TweenLite(mc, 1, {x:100, alpha:0, y:200, paused:true});

var master:TimelineLite = new TimelineLite();
master.append( new TweenLite(baseTween, baseTween.duration, {currentTime:baseTween.duration, ease:Linear.easeNone}) );
master.append( ...other stuff.. );
master.append( new TweenLite(baseTween, baseTween.duration, {currentTime:baseTween.duration, ease:Linear.easeNone}) );

 

Of course it would probably just be simpler to recreate the original tween (baseTween) whenever you need to append it, but this demonstrates a concept that can be very useful especially for timeline instances that have multiple tweens that would be complex to recreate each time.

Link to comment
Share on other sites

  • 1 year later...

I've run into the same problem, but I'm unable to get your solution to work.

Here's what I've tried:

var laserAni:TimelineMax = new TimelineMax();

laserAni

.to(laser, laserFadeTime, {alpha:1, delay:laserDelay})

.from(laser, laserMoveTime, {x:-250 })

.to(laser, laserFadeTime, {alpha:0});

 

var allAni:TimelineMax = new TimelineMax();

//allAni.append(laserAni);//Only runs once if repeated

//allAni.append( new TweenMax(laserAni, laserAni.duration, {currentTime:laserAni.duration} ) );//Implicit coercion of a value of type Function to an unrelated type Number.

//allAni.append( new TweenMax(laserAni, laserAni.duration, {} ) );//Implicit coercion of a value of type Function to an unrelated type Number.

//allAni.append( new TweenMax(laserAni, 3, {currentTime:laserAni.duration} ) );//Property currentTime not found on com.greensock.TimelineMax and there is no default value.

allAni.append( new TweenMax(laserAni, 3, {} ) );//Only runs once if repeated

allAni.append( new TweenMax(laserAni, 3, {} ) );

 

Probably missing somethig simple...

Thanks.

Link to comment
Share on other sites

It appears from your method chaining that you are using the v12 BETA of GSAP.

 

As such, keep in mind that duration is no longer a property. It is a method.

 

laserAni.duration() //gets

laserAni.duration(3) //sets

 

Also, currentTime is now time().

http://www.greensock.com/v12/ (see expanded list of new features / changes for more "gotchas")

 

v12 bad:

allAni.append( new TweenMax(laserAni, laserAni.duration, {currentTime:laserAni.duration} ) 

 

v12 good:

allAni.append( new TweenMax(laserAni, laserAni.duration(), {time:laserAni.duration()} ) 

Link to comment
Share on other sites

Thanks Carl:

I've read thru all the gotchas, but I'm still absorbing all the syntax - you're tuts have been extremely helpful.

 

However, the solution 'v12good' above still only runs once if I append it twice:

allAni.append( new TweenMax(laserAni, laserAni.duration(), {time:laserAni.duration()}) );

allAni.append( new TweenMax(laserAni, laserAni.duration(), {time:laserAni.duration()}) );

I realize there are other strategies to pull this off if need be, but once I encounter an issue, Ie like to get full resolution.

I also tried time:0, though I would think we shouldn't have to specify time. Do we?

Thanks.

Link to comment
Share on other sites

you do have to reset the time to 0.

 

Consider this example:

if I say tween mc's x to 100 and then 5 seconds later I say tween mc's x to 100.

The second time I give that command nothing will happen as the mc's x is already 100.

 

you have 2 ways of resetting the time of your laserAni

 

1: use the set() method

 

var tween:TweenLite = TweenLite.to(mc, 1, {x:100, paused:true});
var tl:TimelineLite = new TimelineLite()

tl.to(tween, 1, {time:tween.duration()})
 .set(tween, {time:0, immediateRender:false})
 .to(tween, 1, {time:tween.duration()})

 

2: use a fromTo()

 

tl.to(tween, 1, {time:tween.duration()})
.fromTo(tween, 1, {time:0}, {time:tween.duration()})

Link to comment
Share on other sites

Thanks a lot Carl:

The first approach failed:

allAni.to(laserAni, 1, {time:laserAni.duration()})
 .set(laserAni, {time:0, immediateRender:false})
 .to(laserAni, 1, {laserAni:laserAni.duration()})
// It plays the first '.to', then Error when it executes '.set':
// #1069: Property laserAni not found on com.greensock.TimelineMax and there is no default value.

 

But the second is a success!

allAni.to(laserAni, 1, {time:laserAni.duration()})

.fromTo(laserAni, 1, {time:0}, {time:laserAni.duration()})//Plays twice

Is actually an improvement because I can control the overall timing of the laser animation.

=========================================================================

I discovered something else I don't understand in this setup:

If I do this:

var allAni:TimelineMax = new TimelineMax({paused:true});

then the original laserAni() will run upon compile.

 

Even when I use a button to:

allAni.restart()

It only plays the animation one time (which is even more confusing).

 

However if I also add

laserAni.pause();// pause the original timeline

I get the behavior that I expect - nothing happens until I click the button, at which time the animation plays twice.

 

Do you see what is going here?

========================================================================

One other clarification:

I remain a bit confused about when to use methods like '.append/insert' vs. '.to/from'

Is it the case that when a timeline is assigned to a var we should avoid 'append/insert'?

 

Thanks a ton.

Link to comment
Share on other sites

first you got the error because you made a mistake

 

bad

.to(laserAni, 1, {laserAni:laserAni.duration()})

 

good: (just like you did in the first .to() in allAni)

.to(laserAni, 1, {time:aserAni.duration()})

 

---

 

As for your unexpected behavior: You must pause laserAni when it is created. Note in my example I use paused:true in the constructor.

 

The tweens that you insert into your timeline are like an external force advancing the time of laserAni. With this technique laserAni is never intended to play() on its own. Its forward advancement is always controlled by tweens in the timeline. In simple terms you are tweening a tween. It may sound weird but it is very powerful.

 

So if you pause allAni and don't pause laserAni, laserAni is going to play on its own.

 

hopefully that helps.

 

---

 

As for the insert/append/to/from I can see how it can be confusing if you are new to TimelineLite/Max.

 

There are 2 approaches to adding tweens to a timeline.

 

1) the most common way is to add tweens to a timeline so that the new tween always starts after the previous tween in the timeline ends. In essence you are adding all new tweens to the end of the timeline. Historically the way to do this was with the append() method, as append means "add to the end".

 

//add tween to the end of an existing timeline
tl.append( TweenLite.to(mc, 1, {x:100} );

 

2) you can also insert tweens at any point in time in a timeline. If you have a timeline with 50 tweens in it already and the timeline has a duration of 20 seconds. You can add a new tween or timeline to the timeline at an exact point in time via the insert() method.

 

//insert a tween 10 seconds into an existing timeline
tl.insert( TweenLite.to( mc, 1, {x:100}), 10 );

 

in v12 it is much easier to add a tween to the end of a timeline with the helper methods to() and from()

 

instead of writing

 

tl.append( TweenLite.to (mc, 1, {x:100}) );
tl.append( TweenLite.to (mc, 1, {y:100}) );
tl.append( TweenLite.from (mc, 1, {rotation:0}) );
tl.append( TweenLite.from (mc, 1, {width:100}) );

 

you can omit all the "append" and "TweenLite" business and do

 

 

tl.to (mc, 1, {x:100})
 .to (mc, 1, {y:100})
 .from (mc, 1, {rotation:0})
 .from (mc, 1, {width:100})

 

note that technically the above code is actually one line of code broken onto 4 lines. The methods are chained together with the dots .

 

.to() appends a TweenLite.to() to the end of tl

.from() appends a TweenLite.from() to the end of tl

 

*note you can also use the methods to offset where they are appended in relation to the end of the timeline

 

tl.to( mc, 1, {x:100}, -2) // append 2 seconds prior to the end of the timeline to overlap with previous tweens

tl.to( mc, 1, {x:100}, 2) //append 2 seconds after the end of the timeline to simulate a 2 second delay

 

if you want to add a tween at a particular time (not relative to the end of the timeline) you must use the insert() method.

 

The best advice I can give you is to bookmark the documentation and consult it often. It was my best aid when learning Timelinelite. Its a great place to get info on all the methods http://api.greensock...neLite.html#to() and properties of all the tools. A majority of my "forum support knowledge" is taken straight from the docs and just re-worded slightly.

 

http://api.greensock...class-list.html

 

I think you will find that there is an amazing amount you can do once you get a handle on some of the basics. It's a lot of fun.

 

-c

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