Jump to content


bug in TimelineLite

Recommended Posts

A coworker came to me for help figuring why his tweens stopped displaying correctly.  We're using version 12, updated today.  He's making heavy use of TimelineLite (and TweenLite, but NOT TimelineMax or TweenMax.)


I believe this is a TimelineLite bug because:


1) I updated my GS classes on February 22 (after this change was made: http://www.greensock.com/v12-api-change/.)  His tweens worked correctly.

2) I updated my GS classes today.  His tweens broke.

3) I rolled back all my GS classes to February 22, but left his and all other code unchanged.  His tweens worked correctly.

4) I updated all my GS classes except TimelineLite to today.  His tweens worked correctly.

5) I updated TimelineLite to today.  His tweens broke.


My coworker is setting useFrames to true and tweening through the frames of MovieClips.  It looks like his clips get stuck on their final frame after the 1st tween, as if they're not being reset to frame 1 for subsequent tweens.  He's using the onComplete callback to reset the clips to frame 1 - maybe the callback isn't being called in some cases.  He's using a lot of TweenLites and TimelineLites, and I don't have the time right now (or ever, probably), to go through all his code and isolate a simple test case for the bug.  I don't think he or I should have to, because in light of my sequence above, I don't see how it could be possible for this not to be a bug in TimelineLite.  I hope you'll look into it.
Link to comment
Share on other sites

Ah yes, I believe I see exactly what the problem is. Thanks for bringing this to our attention. My apologies for the frustration it caused.


The short answer is: please use the attached TweenLite file and let me know if it solves the problem for you.


Here's the more lengthy explanation (feel free to skip this if you're in a rush)...


I bet that your coworker had some fromTo() tweens that he was dropping into a TimelineLite/Max, right? Due to popular demand and to make the behavior more consistent in the framework, immediateRender is true by default now in fromTo(), just like from() tweens always were. You can easily set immediateRender:false on those if you prefer, but I believe the root of the problem had very little to do with immediateRender anyway (I just wanted to point it out so that you were aware of the change). This was a fairly recent change and is mentioned in the change log at https://github.com/greensock/GreenSock-AS3/commit/abe855b88311aa0df6291aeac830a44f789835e9


I believe the problem had to do with the fact that when a tween has immediateRender:true, it renders immediately (duh) which triggers the overwriting logic for that tween. That happens as soon as the tween is created, BEFORE it has a chance to get inserted into any timeline. There's no way for the tween to know if it is going to get put into a timeline or not, so it isn't as though it can just check for that. Anyway, the tween overwrites other tweens of the same target/properties that are scheduled to run concurrently and since the tween wasn't inserted into the timeline yet (thus altering when the tween is scheduled to run), it found overlapping tweens that were set to run NOW. For example, imagine you created 3 fromTo() tweens of the same target and the same properties. Of course the last one would overwrite the previous 2. That's the correct behavior. However, let's say you create those 3 tweens and then immediately decide to sequence them in a TimelineLite - now they're not overlapping at all, thus no overwriting should occur. But it already did. As soon as each one was created, it rendered immediately and triggered that logic. See the issue? 


The new [attached] version of TweenLite still renders immediately, but delays its full instantiation (and overwrite routine) until it renders at a non-zero time (basically, when the playhead moves for the first time internally). 


In summary, the immediateRender:true change in fromTo() was likely causing your coworker's tweens to be overwritten in some scenarios. Again, this only affected fromTo(). If you added "immediateRender:false" to those tweens, it would almost surely solve the problem as well, but we needed to fix the overwrite logic anyway inside TweenLite, so thanks again for pointing this out. 


Link to comment
Share on other sites

Thank you for looking into this so quickly.  Unfortunately, the new version of TweenLite you attached does not fix the problem.  My coworker isn't using fromTo or from - looks like he' s just using TweenLite.to, TweenLite.delayedCall, and timeline.add.

Link to comment
Share on other sites

Well that's disappointing. I'm pretty baffled - you said you're SURE that you tried using the latest version of TweenLite and an OLDER version of TimelineLite and it worked? So the ONLY time you had trouble is when you used a more recent version of TimelineLite?


Is there any way you can provide even a very basic example? It's VERY difficult to troubleshoot blind like this. I looked through the changelog and can't find anything that sticks out as possibly causing the behavior you described (not to mention the fact that thing seem to work fine for all our examples and nobody else has reported similar problems). I'm definitely eager to squash any bugs that exist - I'm just at a loss as to how to verify that there actually is one. 


You're 100% positive that there are no fromTo() calls anywhere either, right? 


What versions specifically did you try? It'd help if you could say something like 12.0.2 worked but 12.0.3 broke, and provide any other details about what is breaking specifically. 


[scratching head]

Link to comment
Share on other sites

I'm the co-worker in question. I wasn't using fromTo before out of sheer ignorance, but I am now and oddly, the problem seems to be fixed.


I'm still somewhat curious as to what went wrong with my old approach in the new version, so here's a rough snapshot of the old and new code:



var myTimeline:TimelineLite = new TimelineLite( { useFrames: true } );
myTimeline.add( [TweenLite.delayedCall(0, subInGraphic, [graphic2]), TweenLite.delayedCall(0, graphic2.gotoAndStop, [1]) ]);
myTimeline.add( [TweenLite.delayedCall(0, graphic2Sound.play), TweenLite.to(graphic2, graphic2.totalFrames, { frame: graphic2.totalFrames, ease: Linear.easeNone } ) ]);



var myTimeline:TimelineLite = new TimelineLite( { useFrames: true } );
myTimeline.add(TweenLite.delayedCall(0, subInGraphic, [graphic2]));
myTimeline.add( [TweenLite.delayedCall(0, graphic2Sound.play), TweenLite.fromTo(graphic2, graphic2.totalFrames, { frame: 1 }, { frame: graphic2.totalFrames, ease: Linear.easeNone } ) ]);



Link to comment
Share on other sites

Interesting. I don't see anything obviously wrong with your old code, although you could make it a bit more concise like this:


var myTimeline:TimelineLite = new TimelineLite({useFrames:true});
myTimeline.call(subInGraphic, [graphic2])
    .call(graphic2.gotoAndStop, [1])
    .to(graphic2, graphic2.totalFrames, { frame: graphic2.totalFrames, ease: Linear.easeNone } );

But again, I didn't see anything "wrong" with the old code. I also tried your code in a basic FLA myself and it seemed to work fine - is there any chance you could post a super simple FLA that demonstrates the broken behavior so that we can compile on our end and see what's going on? I'm really curious. 


Thanks for letting us know it's working now (at least with your revised code). 

Link to comment
Share on other sites

Just an update: tlhinman e-mailed offline and there was indeed an issue in 12.0.3 and it has been fixed in 12.0.4 (just posted). Sorry about the confusion/hassle. 

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.