gTween: Programmatic Tweening for AS3 Developers
There are a lot of great tweening engines out there. Personally, I'm a huge fan of Jack Doyle's TweenLite (and he's been incredibly productive adding new features lately). However, none of these libraries exactly fit the needs of me and my team. I wanted an engine that was small, fast, hugely flexible, and built from the ground up for AS3 and developers.
The result was gTween. gTween is a small (4.5kb), fast (1500 instances, 0.5s duration, ~25fps), instance based tweening class, with a huge number of options and capabilities. You can read about core features of gTween below.
This is certainly not an attempt to displace any of the existing tween engines. Rather, it's simply an attempt to share another option for managing programmatic tweens with the developer community.
For now, I am releasing this as a public beta. It has been loosely tested, but there is so much capability in gTween that I guarantee there are still bugs and edge cases we haven't addressed. Likewise, I am soliciting input on additions or modifications to the API (including the names of specific properties or methods), so it is possible that the API may change in the future.
Quick Feature Overview
| Developer Oriented | Proxy Tweening | Interruptible | Sequencing | Timing Modes | Pause All | Events | Resource Management | Etc |
Developer Oriented (consistent AS3 experience)
gTween is built for ActionScript 3 developers from the ground up. It uses a more conventional instance-oriented model, rather than a static interface. It also leverages the AS3 event model instead of callbacks (see Events). This provides a familiar, consistent experience for AS3 developers to work with tweens.
Here's a simple example of setting up a tween, and listening for the complete event.
var myTween:GTween = new GTween(mySprite, 2, {x:200}); myTween.addEventListener(Event.COMPLETE, handleTweenComplete);
Instances can either be referenced or transient. The former allows for changing values and behaviour on the fly (see Sequencing), and the latter works with smart resource management logic to ensure the tween won't be collected until it is finished running (see Resource Management).
Examples of referenced versus transient instances:.
// hold a reference in myTween, so we can modify it later var myTween:GTween = new GTween(mySprite, 2, {x:200}); // run once, and then free tween for garbage collection new GTween(mySprite1, 2, {x:400});
gTween will also work with any numeric property of any object. You can use it to tween the volume of a sound, the size of an AIR window, or the value of "foo" on a custom object type, as easily as you would tween the x property of a Sprite.
Proxy Tweening
gTween provides a unique proxy property that allows you to work with tween destination values the same way you would work with them on the target object. The proxy object effectively "stands in" for your target object.
This simple example shows how you can use the proxy to move the target object 100 pixels to the right.
myTween.proxy.x += 100;
In the above example, the proxy will retrieve the x value from the target object (if it doesn't already exist as a destination value in the tween), add 100, and set it back as a destination value for the tween.
This is a very powerful feature that takes a little getting used to. Take a look at the proxy listing in the full API documentation for more information and examples.
Interrupting Tweens (make changes on the fly)
With gTween, you can modify your tween while it is playing, and it will attempt to accommodate those changes.
The user closes a panel before its done sliding in? Just reverse() it, and it will slide back closed from its current position. Need to move a sprite to a different location, or add an alpha fade out while the tween is running? Just adjust the values on the fly.
Here's a simple example showing how you can tween a sprite to the location a user clicks on stage. Note that the user can click at any time, and the tween will adjust itself to smoothly reach the destination.
var myTween:GTween = new GTween(mySprite,1); stage.addEventListener(MouseEvent.CLICK,handleClick); function handleClick(evt:MouseEvent):void { myTween.proxy.x = mouseX; myTween.proxy.y = mouseY; }
You can also jump to the end or beginning of a tween instantly with beginning() or end(). Calling end(true) will recursively end sequenced tweens.
Sequencing Tweens (child tweens, and nextTween)
gTween provides three features to allow for sequencing multiple tweens: child tweens, delay, and nextTween.
By using addChild, you can associate multiple tweens to act as children of your tween. These tweens will be synchronized with the parent tween when it runs. You can even choose to synchronize their durations so that they start and end at the same time.
You can also specify another tween to play when a tween ends using nextTween, and specify a delay period that a tween will wait before playing.
The following example demonstrates playing two tween synchronously, followed by a 2 second delay before a third tween plays.
var myTween1:GTween = new GTween(target1,3,{x:20}); var myTween2:GTween = new GTween(target2,0,{x:200}); myTween1.addChild(myTween2,true); // true = synch durations var myTween3:GTween = new GTween(target3,3,{y:50}); myTween3.delay = 2; myTween1.nextTween = myTween3;
Timing Modes (frame, time, or hybrid)
Another unique feature of gTween is support for multiple timing modes. You can use the common time based timing, frame based timing, or a hybrid timing model.
In the "time" timing mode, all durations and positions are specified in seconds, and updates are run at a configurable frequency (ex. every 50ms). This provides tight control over durations, but can use more CPU, and be a bit more choppy in high CPU scenarios.
Using the "frame" timing mode, all durations and positions are specified in frames, and updates are run each frame. This uses a bit less CPU, and allows you to synchronize your tween with timeline animations, but the overall time duration can be unpredictable in high CPU scenarios.
The "hybrid" mode updates each frame, but allows you to specify durations in seconds. Each frame the tween will adjust its position according to the elapsed time since the previous update.
GTween.timingMode = GTween.TIME;
Because it is unlikely developers will change modes during a project, it is specified as a class level property. However, gTween will continue to use the old setting with old tweens, which allows you to change the mode at any time.
Pause All
Being able to pause all tweens can be handy. Pause all of the sprites in your game when the user pauses it, or pause all the active transitions when you open a dialog.
gTween offers a class level pauseAll property that will pause all tweens, without affecting their per instance paused property. Handy!
myTween.paused = false; GTween.pauseAll = true; // pause ALL tweens. trace(myTween.paused); // false
Robust Events
gTween offers three built in events: an activate event that lets you know when a tween starts running, an init event that fires when the tween finishes delaying and starts tweening, a change event that fires each time the tween updates, and a complete event that fires when it reaches its end.
Not enough? gTween allows you to dynamically add custom progress points to your tween that will fire when the tween reaches that point.
The following example shows how you can receive an event when a 3 second tween passes the halfway point (1.5 seconds), and get back a "halfway" string:
var myTween:GTween = new GTween(target1, 3, {alpha:1}); myTween.addProgressPoint(1.5,"halfway"); myTween.addEventListener(GTween.PROGRESS,onProgress); function onProgress(evt:Event):void { trace(String(myTween.lastProgressPoint)); }
Note that you can associate any type of data with a progress point. A string labelling the point, a function to call when you reach that point, another tween to run, anything you want.
Resource Management
Resource management is important. You don't want old tweens hanging around using CPU and memory. You also don't want unreferenced tweens being garbage collected while they are still active.
Besides being developed with the AVM2 garbage collector in mind, gTween also uses a couple of strategies to allow unreferenced tweens to be collected when they are no longer needed, while preventing them from being destroyed when they are needed.
- If a tween is targeted at an object that extends EventDispatcher (like Sprite), it will subscribe itself as a listener to that object for a dummy event while its active. This allows the tween to be collected when it ends, or as soon as its target becomes elligible for collection.
- If its target is not an EventDispatcher, the tween adds itself to a class level collection while it is active. This keeps it from being collected until it is finished running.
gTween has been tested creating 3000 new tween instances per second with no memory leaks.
Additional Features
gTween has a lot of additional features. I'm not going to write about all of them, but here are a few:
- autoHide, sets the target's visible to false when the tweened alpha is 0
- autoReverse, reverses the tween when it ends (and plays it backwards if autoPlay is true).
- smartRotate, rotates in shortest direction
- supports using setSize for tweening height and width on components
- support for updating properties like matrix and colorTransform automatically during a tween.
- jump to any point in a tween by setting position.
- loop a tween by setting nextTween equal to the same tween.
- determine the state of a tween with the state and paused properties.
- roundValues makes a tween round all tweened values before setting them on the target.
Download
To access the API documentation, and download the latest build of GTween, visit the GTween page at gskinner.com/libraries/gtween/.
Please provide any feedback or bug reports in the comments below.
Updates:
Sep 3, 2008: Beta 2 has been released. Learn more about it by clicking here.
Nov 4, 2008: Beta 3 has been released. Learn more about it by clicking here.
Comments (75)
This sounds super powerful and all in 4.5k? Insane. I'm definitely taking this thing for a test drive tonight.
Posted by: Carlo at August 18, 2008 11:53 AMURL: http://labs.alducente.com
Would this API be suited for typed calls, instead of dynamically passing along an {x:60} object? In a scenario where you'd use a lot of tweens in succession, a typo is easily made and sometimes a lot harder to spot at runtime.
I really like the proxy and progresspoints features, by the way. // ep
Posted by: Eric-Paul at August 18, 2008 12:15 PMURL: http://epologee.com
A pain I've felt using another tweening library was the lack of support for passing in an array of objects to be tweened and having them all be tweened the same way. I haven't dived into gTween's code but from the documentation, this doesn't seem to be an option. I'd love to see that option in a future release.
Posted by: Don at August 18, 2008 01:01 PMURL:
Wow. Great! This is exactly what I needed!
But there's one simple feature which keeps me with Tweener (and which can't be found even in TweenMax): rounding. For example when you want to tween a Bitmap to a rounded position in each frame, you have to add an ENTER_FRAME handler to round it for you. In Tweener it's simple: rounded:true.
Is there any chance to add it please?
Posted by: Vaclav Vancura at August 18, 2008 01:15 PMURL: http://vaclav.vancura.org
Looks good Grant. I like the approach and features. I'll give'r a whirl one day.
Posted by: John C. Bland II at August 18, 2008 01:40 PMURL: http://www.johncblandii.com
great job!
Posted by: Ali at August 18, 2008 02:41 PMURL:
Awesome Grant!
Posted by: John at August 18, 2008 03:01 PMURL:
The API docs appear to be out of date --> In the API docs, the constructor GTween takes 5 params: target, duration, object properties, transition function, and auto play. However, the GTween.as constructor takes 4 params: target, duration, object properties, and tween properties.
Posted by: John at August 18, 2008 03:29 PMURL:
No doubt you've tested it extensively, it's quite a fresh approach to tweening with some really nice features. I particularly love the timing modes. Can't wait to play with it. Great work.
Posted by: C4RL05 at August 18, 2008 03:30 PMURL: http://www.carlosulloa.com
John - thanks for catching this! I had forgotten to copy the latest ASDocs over prior to releasing this. I have updated the ASDocs online and in the distribution.
Posted by: Grant Skinner at August 18, 2008 03:57 PMURL: http://gskinner.com/blog/
Looks like some awesome features here. Especially the resource management. Nice work.
I looked through the docs and did not see a way to specify the type of ease or method to use for the tween, like in TweenLite. Am I missing it? If not, this would be certainly be a must.
Posted by: David at August 18, 2008 04:40 PMURL:
Looks sweet - is there any recourse for overwriting tweens? Alternately is there a way to recall an anonymous tween to change it?
Posted by: Rob at August 18, 2008 04:45 PMURL: http://calypso88.com
Found it - transitionFunction
Posted by: David at August 18, 2008 04:48 PMURL:
Welp, so much for convincing anyone to get interested in the idea of collaborating on a community basis to create a base animation library instead of reinventing the wheel. I'll just go put my head under a rock for a while.
Posted by: Moses Gunesch at August 18, 2008 07:41 PMURL: http://www.goasap.org/
Hey Moses, I agree to a point. Collaboration is a wonderful thing for community driven projects like Go and PPV3D. I had very specific needs for this tweening engine, and none of the existing engines were built in a way that would easily accommodate them, without investing a lot more work than it would take to build a new class from scratch.
Once GTween was built for our internal use, it made sense to share it with the community, in case it addressed the needs of other developers. GTween absolutely did not arise from a decision to eschew collaboration or to marginalize or exclude existing libraries.
Posted by: Grant Skinner at August 18, 2008 11:19 PMURL: http://gskinner.com/blog/
Hi Grant! When autoReverse = true, how do I put a delay in between tweens? I want the animation to start immediately, waits for a few seconds and starts autoreversing.
Thanks!
Jon
Posted by: Jon Danao at August 19, 2008 12:04 AMURL: http://danao.org
Nice work! I'm looking forward to playing around with this.
I'm working off an example from a book named Objected orientated action script which shows how to make a tween framework.
Hopefully I'll be able to make something this cool some day :)
Posted by: dub at August 19, 2008 02:17 AMURL:
Looks really good Grant. Gonna try it a bit :)
Posted by: Mr.doob at August 19, 2008 05:05 AMURL: http://mrdoob.com
Is there a greater embarrassment for the flash community than tweening? How hard is it to programmatically make an object go from one place to another? For the love of god shut up about tweening and programmatic animation already, it's not that complicated. Have you ever looked at the source code for Fuse? The horror.
Posted by: Flash Bastard at August 19, 2008 08:49 AMURL: http://sdfsdf.com
Great Work GS
Posted by: Saeed Ashour at August 19, 2008 09:16 AMURL: http://blog.alflash.com/wordpress/
@Flash Bastard: I'm not sure if this is what you meant, but programmatic tweening is one of those things that are so close to the developer and that so much of his/her work end up relying on it that it's just a given that we'll always see a good number of different implementations, each doing things slightly different and fitting better into a different work flow method, and always as abstract and separated from actual projects as possible, as a separate kind of package.
I can't think of anything as frustrating for a developer as using an animation and event chaining framework that he doesn't like, or that doesn't feel natural and transparent, and as such, I'm pretty happy to see a new one around -- and in this case, one done by one of the guys who have been around in the Flash community since forever nonetheless.
And personally, although I haven't done great changes to my own tweening classes (Tweener) recently due to having a lot of real work and a college thesis to finish first, I've been thinking a lot about tweening in AS3 lately and there's a number of features and, specially, different ways of doing stuff that I've kept in mind and on my plans for whenever I have the time to implement it. And surprisingly, most of the stuff I've seen above on gTween's example implementations above follows exactly what I had in mind; I don't meant to say this as some kind of "durr I thought of it first! but haven't written it already! BUT I WIN!", but just that its implementation looks *really* well thought out and matured for our AVM2 needs.
That is all to say, gTween is looking awesome. Thanks, and keep up the good work, Grant.
Posted by: zeh at August 19, 2008 09:51 AMURL: http://zehfernando.com
Grant,
This is phenomenal.
My big question is will gTween allow for custom properties? One of the things that is really nice about Tweener is that if there is not a property for something, I can create & register my own property.
Also, I have yet to find a Tweening engine that allows me to apply one tween to multiple targets in a single command. Will gTween allow for the target to be an array of objects?
Posted by: andy at August 19, 2008 10:11 AMURL:
Andy - Yes, one of my requirements for GTween was that it be completely object agnostic. Other than a few cases for special handling of particular properties (autoHide, smartRotate, setSize), it is completely independent of individual property names. Any numeric property on any object can be tweened with GTween.
Some suggestions that sound like possible additions: multiple targets. Cloneable tweens - this would allow you to set up multiple identical tweens quickly for different targets. Rounded values.
I also need to remember to rename transitionFunction to tweenFunction - meant to do that before release.
Can someone post a good use case for tweening multiple targets with the same tween? I'm thinking a better approach might be a simple Composite pattern implementation that works with GTween, but would like to see the use cases first. Thanks.
Posted by: Grant Skinner at August 19, 2008 10:45 AMURL: http://gskinner.com/blog/
Flash Bastard, tweening is easy, the issues many times is on a particular project to use a library that makes it common (which ever tweening engine suits your or your own). But mainly this helps to make codebases common and teams able to interchange easily on that project. Yes there are lots of tweening engines but it is more about using frameworks for things so that actionscript isn't programmer specific. Before AS3 lots of code was only touchable by the developer because it was a complete mess and unusable in any reuse. All that is changing. And you can see the effects in all the better games, apps, ads etc built with flash and specifically AS3.
Posted by: ryan at August 19, 2008 02:01 PMURL: http://drawlogic.com
Looks very interesting Grant, thanks for sharing! About the name transitionFunction, wouldn't easeFunction work out better than tweenFunction? The latter seems a bit confusing.
What happens if you have multiple tweens working on the same target at the same time, would that work? What about conflicting Tweens which affect the same target properties?
Posted by: Marcus Stade at August 19, 2008 05:10 PMURL: http://www.gimlet.se
Regarding when one might have multiple targets with the same tween, say one was storing a list of display objects in an array. The circumstance can occur where such objects cannot be grouped in a DisplayObjectContainer.
As such I would have to apply the tween to each item individually via a loop through the array. If it was possible to apply the array as the target, it would cut out a hair of code.
Posted by: andy at August 19, 2008 06:06 PMURL:
Excellent class.I've already started using it in my projects. What appeals to me above everything else is the fact it's AS3 oriented. Good job.
Posted by: Dark Vyper at August 20, 2008 03:26 AMURL: http://blog.fatal-exception.co.uk
I don't know, maybe I'm missing something. But where I can find list and documentation of Tween Properties?
Posted by: And at August 20, 2008 03:35 AMURL:
So you use transitionFunction to set the easing? Can you post an example of this?
Posted by: user at August 20, 2008 03:45 AMURL:
Its performance is great with big amount of particles.
Now we have three motion script library in the hand;
1. Fuse Engine
2. Tweener
3. GTween
BTW, Why they all work together for an ultimate one :)
I'll have a test drive with this one and feedback.
Thanks for sharing the work.
Posted by: Ozgur ALTAY at August 20, 2008 04:48 AMURL: http://www.ozguraltay.com
I have tried to sequence a movie first to a position in x and after to a different in y.
It doesn't sequence and goes directly to the final position. Can it be because it has the same target?
var tween1:GTween = new GTween (movie, 3, {x:500} );
Posted by: Paulo Miranda at August 20, 2008 06:31 AMvar tween2:GTween = new GTween (movie, 3, {y:500});
tween1.nextTween = tween2;
URL:
I'm sure this will come in handy when I just need to get something out the door. But I owe Moses my life and am dedicated to Goasap for the long haul.
Posted by: Joel Stransky at August 20, 2008 07:39 AMURL: http://www.stranskydesign.com
And - Do you mean that you'd like to be able to get back a list of the properties that you've set up to tween? Or, you'd like documentation on what properties GTween works with? If the former, if you give me a use case, I'll consider adding the capability. If the latter, the answer is any numeric property.
user - myTween.transitionFunction = Circular.easeInOut;
Paulo - both of your tweens are autoplay by default, so they will both play at the same time. Try setting up your second tween like so:
Posted by: Grant Skinner at August 20, 2008 07:40 AMvar tween2:GTween = new GTween(movie,3,{y:500},{autoPlay:false});
URL: http://gskinner.com/blog/
Excellent ideas in this work. I just tried the custom progress points, and found some strange behaviour.
1.) in class ProgressPoint:
public var data:String;
should be:
public var data:*;
I assume?
2.) Why do you have removeProgressPoint(data); in addProgressPoint? This prevents us from using the same markers (signals) at two different positions, which should be possible, shouldn't it?
But thanks again and keep up the good work!
Posted by: Thomas Rudin at August 20, 2008 10:24 AMURL:
Grant,
Looks super cool and I can't wait to try it out (I especially like the use of events rather than callbacks), but I'm partly with Moses on this one.
I guess the bigger question is why hasn't Adobe sought more community involvement on this topic? I thought for sure that bringing Robert Penner onto the team would have helped. I suppose it did create some nice new features, yet here we are 3 years later and still making our own animation libraries =/
Posted by: Kevin at August 20, 2008 12:16 PMURL:
Flash Bastard: I'll take your little jab on the chin since yeah, Fuse's internal code is a bit ugly. :-) Ironically, I wrote Fuse after I'd already put together a clean & tidy OO system (called Sequencer) -- which to my chagrin crawled like mud in AVM1. I switched to Zigo's unapologetic, down-and-dirty approach b/c it was massively faster, and very tightly synced. I still feel I beat the odds in AS2 / AVM1 by keeping Fuse fast and efficient while offering tons of features. A lot of the lessons from AVM1 are still applicable. For example, animation processes over twice as fast using a synced list system than a more normal OO approach -- it's a fact.
So in the end, I don't think we're coding Flash or Flex so much as coding for the Flash Player. Working with it in its own way can yield some incredible performance gains.
Posted by: Moses Gunesch at August 20, 2008 06:26 PMURL: http://www.goasap.org/
WOW! All this tween drama! I thought the worst was over.
Great work Grant! Setting up a tween library is no walk in the park and I've come to respect anyone who will give it a try. Competition is fierce, demand for new features is high, and optimizing is like shooting in the dark. If we're one more step closer to having a solid implementation built into the player, I'm all for it. I'm looking forward to trying it out.
P.S. KitchenSync r00lz!!!1!
Posted by: Mims H. Wright at August 20, 2008 06:36 PMURL: http://kitchensynclib.googlecode.com
Grant I looked at your library, your proxy idea is interesting.
Posted by: Moses Gunesch at August 20, 2008 06:37 PM(Not really sure why you put all your classes in one file?)
URL: http://www.goasap.org/
Grant, now I'm using GTween in my current project.
I make tiny Flash CS3 project with Flash Components from Adobe (yes, I love Flex, but not only Flex components do exist). At some point I decided to animate the TileList scroll. I overrided its "scrollToIndex" method and used GTween there to animate "horizontalScrollPosition" property — works like a charm!
Question: In the comment above, you mentioned the following:
user - myTween.transitionFunction = Circular.easeInOut;
The question is, where "Circular.easeInOut" besides? Will you provide the tweening functions later, or will GTween consist only from one class, as in the current download?
Thank you for great library. I decided to use it even in the beta because of your previous superior developments. It is very easy to start! Maybe it's just because I was Tweener junkie for year, but I think GTween is really easy to use indeed.
Posted by: Rostislav Siryk at August 21, 2008 06:43 AMURL: http://en.flash-ripper.com/
[...]Nova Engine de Tween para AS3[...]
Posted by: Breno Claizoni at August 21, 2008 07:09 AMURL: http://bocs.wordpress.com/2008/08/20/nova-engine-tween/
Let' me self-comment my own comment where I'm talking like true LOLCat:
>> I overrided its "scrollToIndex" method
I meant 'I overriden', I swear ;-)
BTW, I get further and animated more components in my app with GTWeen. Great tool!
Posted by: Rostislav Siryk at August 21, 2008 11:55 AMURL: http://en.flash-ripper.com/
I tried a sequence tween and it behaved correctly the first time, but every time after that it does both tweens at once.
var menuHolderTween00:GTween = new GTween(this.catMenu, .2, { alpha:0 } );
var menuHolderTween01:GTween = new GTween(this.catMenu,.5,{height:0});
menuHolderTween00.nextTween = menuHolderTween01;
Am I doing something wrong, or is this a bug?
Posted by: Mike Britton at August 21, 2008 03:04 PMURL: http://www.mikebritton.com
great!!
Thanks~
Posted by: Flower at August 21, 2008 07:21 PMURL: http://2rang.tistory.com
This is really a nice job.
Posted by: hbb at August 22, 2008 08:04 AMI prefer instance-oriented mode to static interface.Thanks Grant.
But I have a problem of the event mode that cannot pass custom arguments easily to event handler function.
And if one gtween object add event listener that must be removed explicitly when delete the object.
That maybe become to a trouble?
URL:
Hey Grant! Thank you very much for releasing your new tween engine to the masses, I appreciate it! :)
It looks really powerful (loving the proxy!), but I didn't see an easy implementation for an 'on complete execute this function' method akin to: myTween.onComplete(func:Function);. I will probably just roll my own that listens for the complete event as needed, but it would be great if this was included out of the box. Did I just miss the implementation?
Thanks again!
Posted by: Elliot Chong at August 23, 2008 08:55 AMURL: http://elliotjameschong.com/
@Elliot,
Check out the events section above
http://www.gskinner.com/blog/archives/2008/08/gtween_a_new_tw.html#events
There are built in events for init, activated, and complete, and you can add your own events to any point in the Tween. Note that gTween uses event listeners rather than callbacks, which is an object-oriented approach, and more flexible than an onComplete callback.
Posted by: Lanny at August 23, 2008 11:14 AMURL: http://gskinner.com
I see this in other situations and I always wonder the same thing, especially when it comes to Tweening.
var myTween:GTween = new GTween(mySprite, 2, {x:200});
myTween.addEventListener(Event.COMPLETE, handleTweenComplete);
In this example is there something that makes sure the Event.COMPLETE doesn't fire before the listener is registered? I would think you would want a myTween.start() function.
I haven't dug into TweenLite to verify this but I figured passing in the listeners/events in the constructor guaranteed the Tween won't fire off the Event you need before you are listening for it. (and allows stuff like onStart Events)
Posted by: jacob at August 23, 2008 11:27 AMURL:
I noticed you have a special progress event... do you have something akin to the Tween Class's onMotionChanged? That on is pretty useful.
Posted by: Elliot Geno at August 23, 2008 01:58 PMURL: http://pyrografix.com
mike - when sequencing tweens, you will generally want to set the autoPlay property of the nextTween or child tweens to false:
var myTween2:GTween = new GTween(target,0.2,{height:0},{autoPlay:false});
jacob - you would receive the COMPLETE event ok (because it is delayed at least one frame), however, you would not receive the ACTIVATE or INIT events on a tween with autoPlay set to false. This is definitely an issue I need to resolve in GTween. There are no perfect answers, but I'm thinking through the available options and will select the best one.
elliot - I considered broadcasting a "change" or "tic" event, however I decided not to because it results in a CPU cost for all tweens and I'm guessing it is a rarely used case. I will benchmark it, and if the speed difference is very minimal I will implement one.
Posted by: Grant Skinner at August 24, 2008 03:31 PMURL: http://gskinner.com/blog/
Interesting albeit surprising to see another invention of the wheel spawn from the community. With TweenMax/TweenLite practically being industry standard I'm a bit confused why so much work has gone into creating this.
Be that as it may, how does this weigh up to its alternatives in Memory imprint and processing penalty?
Since at this point there's really very little point in going anywhere with your projects unless something offers a very positive change in performance (like TweenLite/Max over Tweener) because of the impact it has on older projects and a development team, It'd be interesting to see some comparisons before I try it out ;)
Posted by: Erik Hallander at August 25, 2008 05:47 AMURL: http://www.erikhallander.com/blog/
Nice Grant,
Altough i think you can get some more preformance upgrades. TweenLight is 10k but can handle 2500 instances. So untill nyours can handle 2500 i am staying with tweenlight :)
Nice effort though.
Posted by: Rackdoll at August 27, 2008 02:06 AMURL: http://blog.rackdoll.nl
To Rackdoll:
Posted by: Burrows at August 27, 2008 03:09 AMwhat's your meaning of TweenLight?Is that indicate TweenLite?And the weight of TweenLite is about 3K,where are your 10K come from?
URL: http://www.troikaer.cn
Wow to all the developers with negative comments:
----------------------------------------------
Where is the logic in complaining about receiving another avenue for free code? Its not like there are billions of tween engines out there, making it tedious to know which to use ,rather there is enough info on the web to quickly find the top engines out there , and find which one suites your needs. The edge of development is maintained and surpassed by people doing exactly what grant did , by continually providing new/different solutions. Did you say the same thing when the second or third engine found its way onto the internet free of charge ? why say it now .. have the tween saturation limits been reached ? I read a post on joa-ebert's blog where he discussed his new engine he built , which surpasses tweenlites performance and prowl , while not for public release , its still very exciting to know such an engine exists and was built. ( http://blog.joa-ebert.com/2008/05/07/tweening-and-object-pools/ )
Let me show you how you should respond:
Thanks for your work and effort Grant ;)
Posted by: ian at August 27, 2008 03:38 PMURL: http://www.entertainmentafrica.com
I've run into an issue when trying to dynamically alter multiple tween properties using proxy. It seems that combining x, y, scaleX, scaleY and alpha does something to prevent the target display object from being rendered (it just disappears once the tween initializes). Here is a stripped down snippet that should replicate the issue:
var tween:GTween = new GTween(testObject, 1);
stage.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(p_event:Event):void {
tween.proxy.alpha = Math.random();
tween.proxy.x = mouseX;
tween.proxy.y = mouseY;
tween.proxy.scaleX = Math.random() * 1;
tween.proxy.scaleY = Math.random() * 1;
tween.proxy.rotation = Math.random() * 360;
tween.play();
}
The real bizarre part is that by adding another property to be tweened (ie: tween.proxy.width = 5;) or removing one property seems to completely resolve the issue. Any thoughts?
Posted by: Brett at August 27, 2008 04:57 PMURL:
Sorry: x, y, scaleX, scaleY, alpha and rotation.
Posted by: Brett at August 27, 2008 05:02 PMURL:
Hey Grant!
Posted by: Dan W at August 28, 2008 12:48 PMGlad to see your throwing your hat into the Tweening ring!
I just popped over to the TweenLite speed test site (http://blog.greensock.com/tweening-speed-test/) and was surprised to see that you've been added to the list. What's also surprising is that your engine is rendering the particles as concentric circles. Now I don't know what particle generation code is being used to generate this but the result seems a bit odd.
URL:
Maximum performance is not the goal of this tweening engine. Instead I'm shooting for a balance between good performance, and a rich feature set.
With all due respect, if you're choosing your tween engine based on whether it can tween 4000 versus 3000 instances at once, instead of whether it suits your coding style and project types, you are probably very misguided. This is coming from someone that's probably a little too anal about optimization. If you're tweening that many instance, you'd be better off with a few lines of custom code, instead of a tween engine.
Again though, I'm not trying to win anyone over here. If you like your existing tweening engine, or need to be able to tween that extra thousand instances, please stick with it. I'm just providing an alternative way of working with tweens (for free, I might add) that has worked well for my team.
Now that I'm back from FlashForward I'll be working a bit more on gTween, and hopefully will release a new version with some fixes and additions shortly.
I'm also working with Jack to figure out why gTween bands in his test suite, but not in mine (showing 3000 active tweens):
Posted by: Grant Skinner at August 29, 2008 10:49 AMhttp://gskinner.com/libraries/gtween/demos/SpeedDemo.html
URL: http://gskinner.com/blog/
@Brett
I have done some testing in the office with GTween and proxies. I was unable to replicate the issue you reported using the same snippet you posted on the site.
Is there a sample online that demonstrates the object not being rendered correctly?
Posted by: Nick Johnston at August 29, 2008 03:42 PMURL: http://www.gskinner.com/blog
Hi, Grant
First thing i want to tell you : GREAT JOB, MAN.
I'm also a big fan of TweenLite and family.
I found your .proxy to change the end properties very useful, and it's the kind of thing i really want from TweenLite.
Also like the way you split up properties into two object, that will more efficient than one.
But i really don't like the event, i think onComplete, onUpdate, onStart of TweenLite will give the developer much more efficient, especialy who do much about code-animation. Adding onComplete, onUpdate, onStart would be extreamely useful. You may think that i'm not a good developer but it will really handy have these call back functions in hand.
Thanks.
Posted by: thienhaflash at September 1, 2008 05:50 AMURL: http://thienhaflash.wordpress.com
First off, GREAT job Grant. I totally concur with ian who said the proper response to Grant releasing gTween is "THANKS!". He's doing what he's known for doing - innovating and contributing to making the Flash community better.
Regarding thienhaflash's comment (and a few others'), I just wanted to point out that TweenMax (TweenLite's "big brother") has a setDestination() method that is somewhat similar to gTween's proxy, and that you can use TweenLite/TweenMax in an object-oriented manner instead of the static to() and from() methods if you prefer. That's NOT to say it's better (or even as good) as gTween. Just different. www.TweenMax.com
Grant has provided yet another solid tweening alternative, and he has done so in a spirit of generosity. Trust me, it takes a lot of time and effort to put something like this out for everyone to critique and then answer all the questions that come flooding in. If you like it, great - use it and let it make you more productive. If not, use something else, but be careful about complaining especially since it's free!
Thanks again Grant.
Posted by: Jack at September 2, 2008 11:59 AMURL: http://blog.greensock.com
@Nick
So after looking at this again, its even more bizarre than I originally thought. The code snippet I provided consistently causes the issue for me, but only when testing the movie from within the Flash IDE. Opening the subsequently generated swf independently resolves the problem completely, and all tweens to the target display object are rendered as intended. I've never encountered anything like this before, but for all intensive purposes it seems to be a non issue.
Posted by: Brett at September 2, 2008 06:05 PMURL:
I've been using this class more and more lately but I was wondering if it supports bezier curves? I haven't seen anything in the documentation so I'm pretty sure it doesn't, but is that something that may end up in a final version?
Posted by: Alan at September 5, 2008 11:08 AMURL:
I am always surprised at the request for a bezier tween. A tween takes a single numeric property and transitions it from one value to another at a rate described by a curve function.
Posted by: psturgeon at September 15, 2008 12:12 PMA bezier necessarily ties together two variables, and x and a y, and tweens them over time. it also requires a series of points (x,y again) to describe the path to plot to. It necessarily takes a different function signature.
Its a nice animation behavior, but its not a tween.
URL:
Bug or Feature?
First of all thanks for your 'community work' Grant - highly appreciated!
There is a small, but troublesome issue when setting up the sequence of tweens - it is probably worth fixing or clarifying. It seems that depending when autoPlay is set it will or will not take effect. Here are two code sequences to demonstrate the problem:
// this works playing one second tween after the first one...
firstTween = new GTween(target, 1, { x:100 }, { ease:Cubic.easeOut } );
secondTween = new GTween(target, 1, { y:100 }, { ease:Cubic.easeOut, autoPlay:false } );
firstTween.nextTween = secondTween;
// this does NOT work starting two tweens immediately...
firstTween = new GTween(target, 1, { x:100 }, { ease:Cubic.easeOut } );
secondTween = new GTween(target, 1, { y:100 }, { ease:Cubic.easeOut } );
secondTween.autoPlay = false;
firstTween.nextTween = secondTween;
I took a look at the GTween source, but it was not immediately apparent why this happens, so it figured I will ask first... ;-)
Posted by: Tomasz (Tomek) Zemla at September 16, 2008 03:55 PMURL: http://www.pixelbox.com
There are tons of engines out there, including my own, Twease, and all have their strengths and weaknesses, I don't really see the reason to "take sides" (...unless you have your own engine of course heh)
It's kind of like indirect capitalism. We're *really* not "competing" with each other's engines, but when you see somebody else that can do it 5x faster and has some new features, you see that there's room for improvement and it drives you more, creating a better "product". None of us really get money or try and "sell" our "products", but the community as a whole gets better options because of it.
It's kind of funny that we (the engine developers) are totally cool with each other and actually help each other out here and there, yet it's the users that are the one's that get all aggressive about it. But I digress.
Anyways, good work Grant! I'll have to take a look sometime, it looks top-notch. You're more than welcome to checkout the source of Twease on Google code to see if it gives you any ideas or inspiration from its (quite) different approach.
Keep up the great work!
Posted by: Andrew Fitzgerald at September 20, 2008 06:31 PMURL: http://play.visualcondition.com/twease/
Hi Andrew,
I'd like to think part of it is that the type of person that is willing to put a bunch of work into building, documenting, and releasing a major library for free, is unlikely to be the type of person to get all aggressive when someone else does the same.
I'm definitely not in any kind of race, and I don't think any of the other tween engine developers are either. It helps that there really isn't any prize for the winner. :)
Posted by: Grant Skinner at September 20, 2008 09:11 PMURL: http://gskinner.com/blog/
My favourite part of this is the commentary.
I particular liked the part about GTween being object agnostic...
Beautiful!
Seriously though, some of these features are a "god" sent.
/sniggers
Posted by: Ben Charnock at September 22, 2008 07:17 AMURL: http://curlyben.com
Hi Grant. Thanks for making a great product. I have been using it for a few weeks in a project with success. I do have a feature request for you:
It would be nice to be able to link a queue of property changes on the same gTween instance. For instance say I want a sprite to move in a rectangular pattern on the screen. Currently, I am having to set a listener on the tween instance, modify its properties, then call play on it again, all while keeping track of what particular tween took place via a counter.
Instead you could say something like gTween.propertyQueue = [{x:50}, {y:50}, {x:0}, {y:0}];
gTween.autoLoop = true;
gTween.play();
and it would play thru the propertyQueue array, basically automating the nextTween process while using the same instance of the gTween.
Dunno, just would be a feature I would like to see added.
Also, since gTween is leveraging some enterframe/timer event to update the properties on the object being tweened, it would be good to be able to tap into that event so as not to have to duplicate that logic outside of the tween along with some flag to see if we are tweening. I'm lazy ;)
Posted by: j at September 23, 2008 11:41 AMURL: http://jwopitz.wordpress.com
j,
Thanks for the feedback.
The property queue would actually be fairly easy to add. I'll think about that. The workflow I would use right now to tween in a square would be to set up two sequenced tweens:
verticalTween = new GTween(target,0.5,{y:200},{autoReverse:true, autoPlay:false});
horizontalTween = new GTween(target,0.5,{x:200},{autoReverse:true, autoPlay:false, nextTween:verticalTween});
verticalTween.nextTween = horizontalTween;
verticalTween.play();
In the above, the target will be tween vertically to y=200, then horizontally to x=200, then vertically back to its original y position (because of autoReverse), then horizontally back to its original x, then it will repeat.
As to your second request, beta2 (ie. the current released version) has a CHANGE event, which fires whenever properties are updated. I believe that is what you are looking for.
Posted by: Grant Skinner at September 23, 2008 11:48 AMURL: http://gskinner.com/blog/
Hi Grant,
Is it possible to create the Mac OS style distorted tween with gTween?
Great stuff as always
Posted by: gordee at September 25, 2008 02:19 PMURL:
Great stuff Grant. I hope I can contribute to this engine some how.
Posted by: Alan at November 11, 2008 09:24 AMURL: http://blog.alanklement.com
In the "docs" under the setAssignment() method, there is mention of the GTweenFilter method. Is this method available with the Beta 3 release and, if so, can you please give an example ?
Posted by: Anton at November 13, 2008 04:05 AMURL:
I too am looking for info regarding GTweenFilter.
Posted by: Charles Loflin at November 14, 2008 02:58 PMURL:
Hi
I looked at the documentation, at the samples (they dont have a source view option) at the GTween source and still cannot find how I tween between two colors. I tried:
var ct:ColorTransform = new ColorTransform(0, 0, 0, 100, 255, 255, 255, 0);
var tw:GTween = new GTween(theclip, 0.5, { transform:ct }, { ease:Circular.easeOut} );
But it does not work. I also tried using color:ct. I'm not sure how to use GTween.setAssignment()
Thanks for any help.
Posted by: mauricio giraldo at November 14, 2008 04:14 PMURL: http://www.pingpongestudio.com
Ok I managed to solve my color question so I put it here for future reference (had to decompile the sample SWFs in the documentation... :$ )
var coltw:GTween = new GTween(theclip.transform.colorTransform, 0.5, { redOffset:255, greenOffset:255, blueOffset:255 }, { ease:Circular.easeOut } );
Posted by: mauricio giraldo at November 14, 2008 04:34 PMcoltw.setAssignment(theclip.transform, "colorTransform");
URL: http://www.pingpongestudio.com