AS3 – Designing a new tween library

I don’t want to sound grumpy, but I never liked how more and more coders don’t seem to be able to keep things simple. Looks like nowadays you must be an architecture astronaut to be considered seriously.

One of these basic Flash things which should be kept simple is tweening – everybody needs to animate things, but I believe it should be kept as a commodity and not become fatter than your own application code.


Why so serious? We’re just moving clips around.

Fuse Kit’s author Moses Gunesch started the bloat war with GoAsap, a tweening "back-end" that all the other tween libraries would build on top of. Imagine: a library that you can’t even use without wrapping it into another library. Brilliant.

Nowadays one of the most stunning recent library is BetweenAS3, the highest level in tween library engineering with over 100 classes. Admittedly if you ever decide to animate 20k particles with a tween engine this will be your best bet because it was designed for massive tweening, so that’s a good thing if you don’t want to write a loop yourself.

Then when I saw the next major update of TweenLite/Max will climb to nearly 70 classes (woohoo!), I decided I needed a change.

Someone suggested Grant Skinner’s GTween library. Thank you, but no, it has the worst (although original) event system and Grant has other ideas now: he and Jack Doyle from TweenMax have declared they would be going to work together on a new library. Funnily I don’t see this going very far and at best they will share the project so both of them will put their popular names behind it – they seem to have a very different way of approaching this topic…

Designing a new tween library

Even if I decided years ago not to write yet another tween library (I wrote one in AS2 that I eventually replaced with Tweener, then TweenLite), a young colleague of mine started to write one and we had a lot of fun discussions about optimization (hi Steve!).

Optimization is a good thing – Grand Skinner apparently did a great presentation at Flash On The Beach on this topic. I sincerely regret I wasn’t there, but at least I can enjoy Grant’s 100 beautiful slides.

But that’s not only about optimization but also about innovating (even slightly): new libraries fail to bring something fresh. Tweener then TweenLite/Max introduced nice syntax improvements but I believe there is still room for improvement.

How would I improve my daily uses of tweens? First, aren’t you sick of adding these onComplete/onCompleteParams in your tweens? I am. And my colleagues and all the Flash friends I know totally agree (if they don’t just respectfully pretend to).

So I gave it a try during one week-end – I wanted to experiment a few things in terms of syntax and performance optimizations:

  • I tried various combinations of Vectors, Dictionnaries and single/double linked lists – I always liked linked lists :)
  • I initially added objects pooling (BetweenAS3 is great in this regard) but it adds a bit of complexity that I preferred to strip from the current library,
  • eventually, the most important part was to find a reasonable code completion-friendly syntax.

Now let me introduce this new tween library with a cool name: Eaze – it’s lightweight (about 7kb), fast and it introduces a few hopefully refreshing improvements.

Syntax overview:

// note: syntax updated on Nov. 5th
eaze(target).to(0.3, { x:dx, y:dy, alpha:0 })
    .easing(Cubic.easeInOut)
    .onComplete(removeChild, mc);
// alpha behaves like autoAlpha by default
// easing functions are simplified Robert Penner functions

eaze(mc).play("startLabel>endLabel");
// supports frame numbers, labels and a nice "animate from/to" syntax

eaze(target).from(1)
    .filter(BlurFilter, { blurX:5, blurY:5 });
// also animates filter color and supports boolean properties

The library is already almost complete with many little syntax tricks, so check Eaze tween library here – you may like it too…

Mandatory performance tests

Someone immediately asked: so how does Eaze compare with TweenMax in terms of performance?

So I recycled a recycled BetweenAS3 demo, running 20k particles during a few minutes (that’s 20k tweens with 2 tweened properties):

  • BetweenAS3 beta3: 38fps, perfectly fluid, very stable 14-18Mb of memory,
  • Eaze alpha: 35fps, perfectly fluid, 18-32Mb of memory,
  • TweenLite v11 beta: 26fps, a bit choppy, 44-60Mb of memory,
  • TweenMax v11 beta: 23fps, choppier, 55-82Mb of memory.

What does this tell us:

  • the memory minimum is what the engine actually uses, 
  • the memory delta tells about the efficiency of the engine memory management,
  • the framerate tells us, partially, how fast the engine runs,
  • BetweenAS3 has a "perfect" memory management system, I really mean it,
  • Eaze does not have any smart memory management, like object pooling, so it makes the GC work more to free released objects,
  • TweenMax consumes a lot of memory, so the GC does a lot of memory cleaning, and that’s probably what makes the animation a bit choppy.

However, don’t be fooled by these numbers:

  • nobody tweens that much objects,
  • so it really doesn’t matter in "real world projects" and all the tweening libraries are good enough for most uses,
  • and anyway you would be better served by a Vector and a loop to animate thousands of particles.

IMHO, syntax matters… but well, Eaze performance is not bad too ;)

  1. Uwe Holland says:

    First thank you for that nice engine. But how about adding something like this:

    Eaze.to(target, duration)
    .filter(ColorMatrixFilter,
    new ColorMatrixVO()
    .brightness(1.5)
    .tint(0xffcc00)
    .saturation(0));

    For even more type safety and chaining tastiness. Though that needs more classes (jokingly) but would probably avoid typos in the properties of the filter object.
    And you could even push it further by setting the class of the filter within the “value object” and write it that way:


    Eaze.to(target, duration)
    .filter(
    new ColorMatrix()
    .brightness(1.5)
    .tint(0xffcc00)
    .saturation(0));

    Eaze.to(target, duration)
    .filter(
    new Blur()
    .x(4)
    .y(4));

    no? :)

  2. kudoshinichi says:

    I am really interested in developing Tweening engine, too… It’s great to have Eaze to having a look… I found similar thoughts with yours… Actually i’m using my engine that is using single linked list and strip that object pooling, too (i did have it in the previously developed version)… and yes, you are right, faster is better but there is no need chasing for speed… we need a better syntax that provide better code completion (i’m impressed with your syntax)… TweenLite is great but there is no more room for syntax invention that helps better code completion…

    My syntax doesn’t very good as yours but it’s someway clear and easier to remember… you can also have a look here (the code is ugly so no need to check out, just have a look through the syntax if you care about)…

    Surely i will invest time on this eaze… GREAT JOB MAN – just as FD, my favourite AS editor

  3. Pablo says:

    Eaze.to(target, 0.3, { x:dx, y:dy, alpha:0 })
    .ease(Cubic.easeInOut)
    .onComplete(removeChild, mc);

    OMG dude, that´s something new… very smart!!! each function returns the same object… thats sooo cool… this is something new i will save in my brain!

  4. Jloa says:

    Hm, u know guys, i’ve recently developed a sms-chat that supposed to auto-scroll sms-items from the bottom to the top and i’ve faced the fact that none of existed tween libs have animation rounded to integers, i mean if u’ve ever tried animating embedded TextFields u’d probably know that a TextField instance should NEVER have float values around their x/y properties.

  5. Jack Doyle says:

    Hey Philippe. Congrats on Eaze, man. Cool stuff. I just wanted to chime in on two things:

    1) Were you aware that there’s a huge flaw in the BetweenAS3 speed test? It has TweenMax tweening Sprite objects which use 12.6 times more memory and require 2.2 times more processing power to update x and y properties compared to the Point objects that they tween with BetweenAS3! It’s no surprise that the test makes it look as though TweenMax is a memory hog and slower. Did you correct the flaw when you ran your tests? If not, it’d be cool if you’d do so and edit the results.

    2) I always find it curious when people seem to think there’s an inverse relationship between the quality of a platform and the number of classes it employs. Originally, TweenLite was a single class and the simplicity was great. But I think you’ll find that as the platform matures, it makes a lot of sense to break things out into classes in order to benefit from inheritance and minimize file size when not all of the classes are needed (true in most scenarios). You complained that TweenLite/Max now have almost 70 classes but in reality, TweenLite is only 4, TweenMax is one more, and the rest are optional plugins. I think the days of “cram everything into one big class file” are largely [pardon the pun] over.

    Anyway, best of luck with Eaze. It certainly does sound fast and I’ve got a lot of respect for anyone who throws their hat into the tweening engine ring because I know how much effort goes into creating one that works reliably and fast and at the same time tries to balance feature richness with minimum file size while putting together good documentation and supporting end users. Prepare for lots of questions :) And if you’ve got any suggestions for the GreenSock stuff, I’m all ears.

    Cheers!

  6. Philippe says:

    Hello Jack,

    1) I’m doing all my tests after updating the libraries to the latest available – I respectfully did it when doing my speed comparisons. I’ll still check that I had the latest release of your lib and update the numbers accordingly.

    I’d like to mention that your own speed test (which I tried too) is flawed by your “FAST” trick which use specialized strongly typed objects to appear faster than other engines in your demonstration.

    2) I never said that more classes is a sign of poor quality: when TweenLite was one class the code was arguably poor (v11 code looks good to me) but at this time you provided a nice little syntax improvement over Tweener. On the opposite, BetweenAS3 has definitely a great design and code quality, but a hell of a lot of classes.

    Now I don’t expect a lot of popularity for Eaze – as for FlashDevelop I like developing my own tools and I enjoy sharing them.

    Finally, I’d have a suggestion for TweenLite: provide small, focused, source archives without FLAs and all. Like only TweenLiteNano AS2 that I’d happily give to my animators to drop in their banners work.

  7. Jack Doyle says:

    I totally didn’t mean to insult or offend – sorry if my comment came across that way. I meant it primarily as a “congrats!” and just 2 points of clarification.

    The flaw mentioned in #1 didn’t have so much to do with using an outdated version of TweenMax – it was that the BetweenAS3 test itself tweens Sprites in the TweenMax flavor of its test which use 12.6 times more memory and require a lot more processing to update whereas it tweens Point objects in the BetweenAS3 flavor of its test – not at all fair. I’m sure it was probably an honest mistake on their part and I was just hoping you spotted it and corrected it before running your tests. The big difference in memory use you reported made me suspect that the flaw may still be present (it’s easy to miss).

    I’m confused as to why you called the “FAST*” stuff in my test a flaw and a “trick”. I include the standard versions in my test as well and clearly explain the difference in the text below. People can try both and see the difference for themselves. The point was to demonstrate what is easily possible with plugins. Were you aware that BetweenAS3 uses the exact same technique (strong data typing for DisplayObject properties) to improve its speed?

    I haven’t provided FLAs in the TweenLite/Max zip downloads for quite a while. Did you mean that you’d prefer that I not provide the swfs like Plugin Explorer and the basics demo? A lot of people have specifically asked for those to be included, but I can see why they might be annoying for knowledgeable developers like yourself who just want the code and no extras.

    Anyway, please don’t take my points of clarification as insults or discouragement at all – you’re obviously a very talented developer and have invested a lot of thought and time in Eaze. I don’t want it to be a “my engine is better than yours” thing at all – the community really benefits from generous guys like you who share ideas and code. I just thought you might want to know about the Sprite/Point discrepancy in the BetweenAS3 test you’re using (again, it’s very easy to miss).

  8. Philippe says:

    Jack, I’ve happily welcome each of your comments – I have the most sincere respect for your work and I feel honored and not insulted by what you wrote :) If I happen to compare my modest library with yours it’s because I believe TweenLite/Max is the reference library nowadays.

    The test from BetweenAS3 that I am using is fair with all the engines and using only the generic tweening features. Maybe I should have mentioned that the results of other libs like Tweener, Adobe Tween or gTween are ridiculous compared to the 3 libs we are discussing.

    That said, I insist that my conclusion is that coders should give little importance to speed and memory aspects and use what they are more comfortable with.

  9. pnico says:

    Re GoAsap: I’ve had a look at Go and have my own issues with it, but the fact that it at least makes an attempt to be flexible is Good, not bad as you clearly suggest. Most other libraries make it very difficult to plug in outside code especially involving sequencing, timing and updates, which limits their usefulness, or worse.

    Unfortunately all of these libraries seem to save state information, and sometimes even complex data structures containing references to all existing tween-related objects, in static variables that are hidden from the user. This can make it very difficult to avoid subtle bugs and memory leaks, especially in larger or modular applications.

    I would take a clean, simple design, modularity and extensibility over performance any day as long as performance is “good enough”. It continues to escape me why all anyone cares about is raw benchmark performance.

  10. Philippe says:

    pnico, thanks for your input – I definitely conclude my posts noting that raw performance should not be a top priority but sadly this is the first question people ask.

    Honestly after many years of Flash animation and dev I have yet to find a project that I couldn’t have done comfortably with even the most basic tween engine.

    Also the fact that you will usually not manipulate tween object yourself (even if it’s possible with Eaze) is imho a better security against memory leaks because the engine was designed and tested to be careful about that. I’d be more anxious to have beginner devs with an object-base tween engine (like Adobe’s) where you must keep tween references to be able to override or stop them.

  11. Thorsten says:

    Salut Philippe,

    Why don’t You work on a JavaScript/JScript/webKit-Tween-Library ?

    JQuery is just so ugly with all these nested anonymous functions !

    Bon courage avec “Eaze” !

  12. Philippe says:

    @Thorsten I definitely think about doing a JS version of the engine ;)

  13. Thorsten says:

    Stop thinking about it. Do it ! The world is waiting for it…

  1. [...] actionscript sensai master or something. When starting the animation part, I was very inspired by this post, which has the same idea of combining jQuery-syntax-style with tweening, which I was already using [...]

  2. Chain Tween says:

    [...] actionscript sensai master or something. When starting the animation part, I was very inspired by this post, which has the same idea of combining jQuery-syntax-style with tweening, which I was already using [...]

Leave a Reply