Jump to content

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

Plugins and TweenMax.from()

Recommended Posts



I'm writing a plugin for a project I'm working on and I'm running into an issue where my plugin's init method is called twice when used in conjunction with TweenMax.from().  Is this by design or am I making a mistake somewhere?  Consistently, the sequence of calls is init(), set(1), set(0), init().


Any insight you could give me on this behavior would be greatly appreciated.



Link to comment
Share on other sites

From tweens are rendered differently, so the two calls are normal. However, setting immediateRender to false in your tween should stop the sets from being called before it renders for the first time.

TweenMax.from(foo, 1, {
  myPlugin: 2,
  immediateRender: false
Link to comment
Share on other sites

Thanks for the reply.


I don't have an issue with the set()'s being called, but rather with the init()'s being called twice.  It seems like the first call is made for from() and then the second call to init is for to().


Is this correct?

Link to comment
Share on other sites

Yep, that's perfectly normal. It helps avoid some edge cases where a plugin, for example, does some fancy rendering or changing of values that could affect the start/end values that get recorded in the tween. So it basically leverages a zero-duration to() tween to force the values to their "from" state, and then runs its logic cleanly against whatever results after that. I know it may seem a little odd, but trust me - over the years we've run into various complexities particularly with a full-fledged sequencing system with random access on timelines that expose the need for this sort of thing. 


Another time you'll see multiple calls to the plugin's init is for fromTo() tweens because they're a unique beast; technically when you put them into a timeline, there are 3 distinct states that must be recorded. Let's imagine a scenario:

var obj = {x:0}, 
    tl = new TimelineLite();
tl.fromTo(obj, 1, {x:100}, {x:200});
//then later...

Where should obj.x end up? The fromTo() is from 100 to 200, so some may think that it should end at 100 (since it's reversed), but in practical reality, most people expect it to end at 0 because that's what it was before the timeline started. So we've gotta track the 3 states: 0 (before the tween started), 100 (the "from") and 200 (the "to"). Consequently, we do a zero-duration to() tween internally and store that so that when the playhead goes backwards before the start, it'll render that initial value properly. 


Also, we had to build the system to allow for plugins to flag the need to re-initialize particularly for overwriting scenarios. For example, imagine a plugin that does motion-blurring by manufacturing an element that gets swapped in for the original but then that tween gets overwritten halfway through. The new tween may be looking for the original target and attempt to read various values but they're obscured by what the other tween had been doing. Thus, when the old tween/plugin gets overwritten, it says "hey dude, I changed some stuff that probably affects the way other tweens instantiate their values, so re-run that instantiation logic on the stuff I just cleaned up for you". 


So you shouldn't build your plugin with logic that assumes it'll only have the init function called once per tween. :)

  • Like 1
Link to comment
Share on other sites

Alrightie, thank you for the very thorough response. 

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.