Jump to content
Search Community

Timeline TweenMax TweenCore relationships

lcornejo test
Moderator Tag

Recommended Posts

Jack,

 

I know there has to be some type of overwriting going on, but, if I have the following sequence it seems that I loose my TweenMax reference

 

var t:TweenMax = TweenMax.to(do, 1, {x:100});

 

//in a local function

function a():void{

var tl:TimelineLite = new Timeline();

 

tl.insertMultiple([t, TweenMaz.to(otherDo, 2, {y:12}])

}

//the animation occurs

then later in the runtime after the timelineLite instance finishes; I execute

t.reverse(); //or any other tweening commands, but no dice

 

one can query the state /properties (reversed, paused, etc) but actually firing the referenced TweenMax instance no longer executes the animation. I suspect that once the 't' in inserted into the TimelineLite instance the actual animation responsibilities are govern there. Can you shed some light on this? If our 't' reference is not able to call the tweening fuction, should it not error out somehow.

 

I know I can just call TweenMax.to again on the target but the t.reverse() seemed like a nice clean way to just reverse that animation, so that I don't have to get the tween of the target then test. It just seems odd to me specially since the TimelineLite instance is only inside the function a scope. Thoughts?

 

I tried looking through the forums and I didn't see a similar topic.

 

Thanks!

 

-Luis-

Link to comment
Share on other sites

taking the timeline out of the function a scope will make this work:

 

import com.greensock.*;

var t:TweenMax = TweenMax.to(do, 1, {x:100});
var tl:TimelineLite = new TimelineLite();

//in a local function
function a():void{

tl.insertMultiple([
			   t, 
			   TweenMax.to(otherDo, 2, {y:12})
			   ])
}

a();


stage.addEventListener(MouseEvent.CLICK, reverseT)

function reverseT(e:MouseEvent):void{
trace(t.currentProgress);
t.reverse();
}

 

i don't know the exact why or how of this. like you said it is sort of confusing that with the timeline declared in the function, t.currentProgress works but not t.reverse(). I'm sure there is a good reason.

 

Carl

Link to comment
Share on other sites

I'd need to see the rest of your code to diagnose this for sure, but it sounds like maybe you've got multiple "t" declarations going on or maybe there's a timing issue, but I can assure you that inserting a tween into a TimelineLite/Max will NOT cause the reference to be lost somehow. There must be something else going on. Could you post a super simple FLA that demonstrates the issue?

 

I also wonder what you meant by "no dice" with the reverse() thing - was an error thrown or did it just not perform as you expected? Keep in mind that a tween's timing is always controlled by its parent timeline. Think of it like a MovieClip timeline in the Flash IDE - if you put a tween on a MovieClip timeline so that it starts at frame 500 but the playhead is only on frame 10 of that MovieClip, you won't see that tween play yet until you get to frame 500. If you reverse the tween, it does automatically adjust its startTime accordingly but if its parent timeline is paused or hasn't started yet, you won't see that tween until the timeline's playhead reaches its startTime. If you haven't watched the video at http://www.greensock.com/timeline-basics/, I'd highly recommend it.

 

Again, feel free to post a super simple FLA that demonstrates the issue and I'd be happy to take a peek.

Link to comment
Share on other sites

ugh. completely ignore what I said earlier. When I was "testing" what I thought was a fixed approach... I was reversing the tween while the timeline was still playing.

my whole move the timeline declaration out thing was completely wrong as I was testing it wrong.

 

attached is a file that illustrates the problem. when timeline completes (box2 fades out) box1's tween will not reverse but it's properties can be referenced as the original poster mentioned.

 

click on the stage to reverse the tween. if timeline is playing, tween can be reversed, if timeline is finished it won't reverse.

 

Carl

Link to comment
Share on other sites

Ah yes, I see where the confusion is coming from. This is actually expected behavior - let me explain:

 

Once an independent TimelineLite or TimelineMax finishes, it automatically removes itself from the rootTimeline to accommodate garbage collection (great effort has gone into making all the tweening classes very gc-friendly, protecting you from gc when necessary and also releasing things when necessary). You can still restart(), play(), reverse(), etc. that TimelineLite/Max and it'll automatically add itself back onto the rootTimeline. But altering the tweens that are nested inside that TimelineLite/Max doesn't force it back onto the rootTimeline because...well...gosh, the explanation would take a while so I'll spare you (I can give you the full rationale if you want, just ask).

 

Anyway, the solution is relatively simple: just play() your TimelineLite/Max after you reverse() your nested tween. That'll force it back into the rootTimeline so that it renders again. There are some other solutions available too, but this is the simplest one. In your case:

 

t.reverse();
tl.play();

 

Does that make any sense whatsoever? Sometimes I'm not sure if my explanations are the least bit understandable to folks that aren't intimately familiar with the architecture of the platform. There are a surprising amount of intricacies involved with building a tweening platform so the explanations can get a little tricky at times. Something that might seem intuitive in one scenario can actually be totally unintuitive when you think of it from another angle. For example, if your TimelineLite completes and then you reverse() a nested tween, should the timeline fire its onComplete again when that tween is done even though you didn't ask the TimelineLite to play() again? And how should the internal relationships between the nested tweens be affected if a 2-second tween that used to have a startTime of 0 is then reversed 10 seconds after its parent timeline completes - should its new startTime be 12? What if its previous duration was 2 seconds (wrapping that 2-second tween) - should it now be 14? Anyway, my point is that you might think "well duh, if I reverse() a tween, it should instantly start playing in reverse" and that is indeed how it works with independent tweens, but when you start dealing with sequences where relative timing relationships come into play, it makes things more tricky.

Link to comment
Share on other sites

  • 2 weeks later...

Makes sense to me Jack,

 

I just think that a small mention of this expected behavior in the TimelineLite docs would help a lot. I understand trying to keep the framework as memory friendly as possible, but I had no idea there was a rootTimeline that manages the rendering of the actual TweenCores (I haven't perused the source long enough).

 

Quick note: is there not a way to check if a TweenCore target has another TweenCore instance associated with it, and if so, not remove it from the rootTImeline, would that not guarantee the "expected" behavior? Maybe a deeper explanation would tickle my fancy but only for intellectual stimuli, your workaround above suffices for moving forward.

 

Best,

 

-Luis-

Link to comment
Share on other sites

I'm not quite sure what this means:

...if a TweenCore target has another TweenCore instance associated with it...

Could you give me some more details about what you mean? Are you talking about a TimelineLite/Max that contains a tween of a particular target?

Link to comment
Share on other sites

...if a TweenCore target has another TweenCore instance associated with it...

Could you give me some more details about what you mean? Are you talking about a TimelineLite/Max that contains a tween of a particular target?

 

what I mean is that if you have some sort of registration service/mechanism that the rootTimeline manages (so that it keeps track of different TweenCores that are tweening properties of the same target), before you remove it for gc, can it just check whether it should remove it or not from the rootTimeline when a timeline instance is done.

 

I kind of recall in previous versions that you had a "persist" option for tweens, that might of allowed us to proactively "tag" a TweenCore to tell the engine not to remove that particular tween.

 

 

Again, this might be a moot point, it might not be necessary/useful if there is better strategies about the reuse of tween references. How would you recommend ways to manage a common tween animation that might be reversed alot (like complex rollover/rollout effects). I like to keep a reference of the tween animation, lets say for various UI hints/eye candy, so that I can play/reverse the tween whenever needed, but sometimes it can also be added into a larger temporary timeline. For example, if you want to append a whole sequence of animations when reacting to a very deeplink or application state (in the case of a heavily animated web app/RIA etc). I figured this should give a performance boost by having the tweens in memory. Or should every tween be a new TweenCore and not keep references to any tween?

Link to comment
Share on other sites

Again, this might be a moot point, it might not be necessary/useful if there is better strategies about the reuse of tween references. How would you recommend ways to manage a common tween animation that might be reversed alot (like complex rollover/rollout effects). I like to keep a reference of the tween animation, lets say for various UI hints/eye candy, so that I can play/reverse the tween whenever needed, but sometimes it can also be added into a larger temporary timeline. For example, if you want to append a whole sequence of animations when reacting to a very deeplink or application state (in the case of a heavily animated web app/RIA etc). I figured this should give a performance boost by having the tweens in memory. Or should every tween be a new TweenCore and not keep references to any tween?

 

This should largely be a moot point with the new system. Generally you wouldn't reverse() subtweens that are in a larger TimelineLite/Max sequence (at least I'm having a hard time thinking of why things would be structured that way - you'd typically reverse() the whole TimelineLite/Max or an independent tween that's just on the rootTimeline). And to be clear, TweenLite/Max doesn't destroy tweens/timelines when they're done. All of their properties remain in tact and they can be used again as much as you want - it's not like some other tweening engines that use object pools that force objects to get scrubbed clean which can screw up your ability to reuse things. TweenLite/Max simply release things so that if you don't have a reference to them, they'd become eligible for gc (as they should) but if you have a reference somewhere, gc won't kick in (that's just how AS3 works anyway). So you could restart() a tween whenever you want. That was a long-winded way of saying that no, there's not a reason to have a "persist" property with the new/better system in v11.

 

The only thing that could possibly prevent a tween/timeline from rendering has to do with timing/scheduling in extremely rare edge cases, not destruction of the instances themselves. Like if a TimelineLite/Max has been completed for a while and then a nested tween inside that TimelineLite/Max is reversed or something, but again I can't imagine why anyone would do that rather than reversing the whole TimelineLite/Max. And there are ways of working around that edge case already anyway.

 

As far as reusing instances or not, either way is fine. Frankly I think a lot of developers have the wrong impression that creating new instances is a big "no-no" and is super expensive performance-wise and that's not true at all. Creating new instances when you need them is a perfectly valid way to do things and can even reduce memory usage slightly compared to keeping lots of references hanging around that can't get gc'd. I highly doubt you'd ever notice even the slightest performance degradation by just spawning new tweens each time you need 'em. As you know, I've put a ton of effort into optimizing performance in the whole system, so go ahead and go crazy. :)

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