Jump to content
GreenSock

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

Combining actual IDE timeline with TimelineMax

Recommended Posts

Hi all,

I have an interesting conundrum.

I want to combine animation done with code , and animation done on timeline.

so I have this:

myTimeline.append(_element_1.animateIn());
myTimeline.append(_element_2.animateIn());
myTimeline.append(_element_3.animateIn()));
myTimeline.append(_element_4.animateIn()));
myTimeline.play();

 

every element :_element_1 _element_2 ... etc, returns TweenMax- TweenLite instance through it's method animateIn() And it all works fine.

 

Now I want to combine elements that have flash IDE timeline animations with TimelineMax , so I can have combination of elements (some use TweenMax , some have timeline animations)

 

I need a solution to push IDE animations to TimelineMax

 

One solution that I can think of is:

I need to pass the instance of the TimelineMax to the element that has ide animation.

And also to return a generic instance of TweenCore() from the animateIn() method in order to satisfy the "append" method requirement

animateIn($sequencer:SimpleTimeline):TweenCore

myTimeline.append(_element_1.animateIn(myTimeline))

 

And then when I'm inside the animateIn method , i stop the TimelineMax instance from advancing further?

Am I on the right track about this , or there is a better solution?

Link to comment
Share on other sites

Nah, all you need to do is use a frame tween to control your MovieClip timelines. So, for example, let's say you have a MovieClip that is 10 seconds long (300 frames at 30fps) and you want it to play after your other ActionScript tweens in your TimelineMax. You could do something like...

mc.stop();

var tl:TimelineMax = new TimelineMax();
tl.append(...append your other tweens here...);
tl.append(...and more...);
tl.append( new TweenMax(mc, 10, {frame:300, ease:Linear.easeNone}) );

 

The cool thing is that you still have total control via the TimelineMax - you can stop(), resume(), restart(), and even reverse()!

Link to comment
Share on other sites

oh, I totally forgot about FrameLabel plugin :oops:

 

I have another question:

Is there a way for me to dynamically set the duration of the tween , because number of frames between the labels won't always be the same ?

this is my timeline:

WIhsu.png

 

As you can see IN_START animation starts on frame 20 , and finishes on frame 40 , if the FPS is 30 , duration should be 20/30 = 0.66

But if the designer decides to move the IN_COMPLETE to frame 60, then the calculation will be wrong.

Is there a way to dynamically but the correct timing every time, no mather where the designer moves the IN_COMPLETE label?

 

I've played with TweenMax "useFrames" property, but I don't really get it ?

 

One solution that I can think of right now is to use MovieClip frameLabels and flash.display.FrameLabel

and for every clip that is used , I would calculate the time for TweenMax tween , based on the number of frames between labels, and the current frame rate of the swf?

 

Am I complicating everything again, is there an easier solution?

 

How would you approach this?

 

Thanks

Link to comment
Share on other sites

Yeah, you've got the general idea exactly right. Here's a method that wraps it into a relatively easy to use technique:

 

TweenPlugin.activate([FrameLabelPlugin]); 

TweenLite.to(mc, labelTweenDuration(mc, "IN_COMPLETE"), {frameLabel:"IN_COMPLETE", ease:Linear.easeNone});

function labelTweenDuration(mc:MovieClip, label:String, fps:Number=NaN):Number {
var labels:Array = mc.currentLabels;
if (isNaN(fps)) {
	fps = (mc.stage != null) ? mc.stage.frameRate : 30;
}
var i:int = labels.length;
while (--i > -1) {
	if (labels[i].name == label) {
		return Math.abs(labels[i].frame - mc.currentFrame - 1) / fps;
	}
}
return 0;
}

 

Notice you can optionally define an fps, but if you don't it'll try to figure it out automatically.

 

And of course you could wrap all of that into a method of its own that makes it even simpler to tween to a particular label (assuming you don't need to tween anything else in that same tween (just the label):

 

function createLabelTween(mc:MovieClip, label:String, fps:Number=NaN):TweenLite {
   return new TweenLite(mc, labelTweenDuration(mc, label), {frameLabel:label, ease:Linear.easeNone});
}

 

(which piggy-backs on the previous method)

 

Hope that helps.

Link to comment
Share on other sites

So that's the way to go.

Thank you for the code Jack.

The more I dig in to the platform ,the more a realize how powerful it is.

 

off topic:

Do you have any future plans to port the platform to JS?

Link to comment
Share on other sites

Do you have any future plans to port the platform to JS?

No comment :) I'm considering this, but haven't made a final decision yet.

Link to comment
Share on other sites

  • 1 month later...

Just a thought -- would using fromTo with labels at the start and end of the tween achieve the same result, i.e:

TweenMax.fromTo(MC_Anim, 3,  {frameLabel:"move_start"}, {frameLabel:"move_end",ease:Linear.easeNone});

...seemed to work for me :)

Link to comment
Share on other sites

  • 7 months later...

Jack,

Thank you for this handy function!

 

Openglpwr, the point of the functions that Jack provided is that they ensure exact timing as defined on the Flash IDE timeline instead of relying on numbers passed into greensock Tween constructors - "3" in the fromTo example you provided.

 

To get fromTo functionality and still preserve the nice timing you've set up in the Flash IDE you'd have to modify Jack's function a little bit:

public static function labelTweenDuration( mc:MovieClip, startLabel:String, endLabel:String, fps:Number=Nan ): Number 
{
var labels:Array = mc.currentLabels;

if (isNaN(fps))
	fps = (mc.stage != null) ? mc.stage.frameRate : 30;

var startFrame:int;
var endFrame:int;

//find the frame numbers of the labels we're tweening between
var i:int = labels.length;
while( --i > -1 ) 
{
	if( labels[i].name == startLabel ) 
		startFrame = labels[ i ].frame;

	if( labels[i].name  == endLabel )
		endFrame = labels[ i ].frame;
}
return Math.abs(endFrame - startFrame - 1) / fps;
}

 

The main difference is that we're now calculating the number of frames between the startLabel and endLabel, not the currentFrame and endLabel.

 

Similarly, we have to make a tiny tweak to the createLabelTween to take in a second label parameter as follows:

 

public static function createLabelTween( mc:MovieClip, startLabel:String, endLabel:String, fps:Number = NaN ): TweenLite 
{
return TweenMax.fromTo( mc, labelTweenDuration( mc, startLabel, endLabel, fps ),
			{ frameLabel:startLabel }, { frameLabel:endLabel, ease:Linear.easeNone });
}

 

 

To wrap things up, with these two functions, openglpwr's Tween changes from

TweenMax.fromTo(MC_Anim, 3, {frameLabel:"move_start"}, {frameLabel:"move_end",ease:Linear.easeNone});

to

createLabelTween( MC_Anim, move_start, move_end );

 

and best of all, it is now guaranteed to preserve the timing that was defined in the Flash IDE, not the possibly arbitrary value of 3 seconds.

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