AS3 – Eaze tween library update

Let’s state it again: "tweening" is a commodity with plenty of alternatives, which means you’re not obliged to use a) crappy ones, b) bloated ones, and c) commercial ones.

Like many Flash developers I started developping Eaze because a) it’s fun, b) it’s (mildly) challenging, and c) I really had a few ideas to innovate in this field.

Since then I had the occasion to discuss (I should say brainstorm) with other Flash developers (hi Joshua and Steve) about our "tweening needs" (sounds dirty, isn’t it?) and our idea of the perfect library. This was very entertaining and they all gave me lots of crazy syntax ideas which turned out to be possible…


Here’s the big change

Internally Eaze has not changed much – I optimized one or two things, improved timing precision. But the syntax has changed enough to break existing code.

The first big breaking change is the entry point: the static Eaze class is now replaced by a package function, eaze(target), which returns a EazeTween instance wrapping the target. Now if you ask me, I feel that’s jQuery-like!

// before
Eaze.to(target, duration, params);
Eaze.delay(duration).chainTo(target, duration, params);

// after
eaze(target).to(duration, params);
eaze(target).delay(duration).to(duration, params);

This change doesn’t look like a big deal, but I think the syntax can hardly get better. In particular, I was seriously annoyed by the confusing static to()/from() versus instance’s chainTo()/chainFrom(). Say "thanks" to package functions 🙂 This little used AS3 language gem is just brilliant (however you can only add one public package level declaration per file, and this is just lame).

New features

I didn’t only fiddle with syntax, but also added some important features like ColorMatrixFilter:

eaze(target).to(duration)
    .filter(ColorMatrixFilter, { brightness:0.5, saturation:-1 });
// brightness[-1/1], contrast[-1/1], saturation[-1/1], 
// hue[-180/180], tint[RGB]/colorize[0/1]

Other "big" new feature is Bezier support… Ok, this is something that I actually only used a few times, but I’ll object that now, in Eaze, this is such a commodity that you may find yourself using Bezier tweens a lot more!

// tween using any number of control points [c1, c2, c3..., p2]
eaze(target).to(duration, { x:[80, 100], y:[100, 0] });
// tween through any number of points [[p2, p3, p4..., p5]] (dbl array)
eaze(target).to(duration, { x:[[80, 100]], y:[[100, 0]] });

Last notable change is tint handling – now the parameter can either be a uint color, or an Array where you can optionally quantify the colorization and a color multiplier:

eaze(e.target).to(1, { tint:0xffffff }); // classic
eaze(e.target).to(1, { tint:[0xffffff, 0.5] }); // 50% tint
eaze(e.target).to(1, { tint:[0xffffff, 0, 1.5] }); // 50% lighten
eaze(e.target).to(1, { tint:[0xffffff, 0, 0.5] }); // 50% darken

Eaze features list:

  • alpha has autoAlpha behavior (use autoVisible to keep the element visible),
  • tint (see “New features”),
  • frame (alternatively, use eaze(target).play(frame)),
  • volume (anything with a soundTransform member),
  • filters (BlurFilter, GlowFilter, DropShadowFilter and ColorMatrixFilter),
  • Bezier (see “New features”),
  • short rotation (TODO, still thinking about the syntax).

That’s a lot of features I think, weighting under 9Kb in the final SWF. Oh and according to Jack “TweenLite/Max” Doyle’s tweening speed test, Eaze is the fastest library around. Yep.

Learn more / download Eaze, it’s free and open source (non-restrictive MIT license).

62 thoughts on “AS3 – Eaze tween library update

  1. Pingback: HIDIHO! » Blog Archive » Eeeeeeeeeeazy :)

  2. I’m a big fan of jQuery and I love you library so I will try it for sure in the next project. Good job!

    I would still opt for Eaze.to(target, …) or even renaming static function to Eaze(target) for people who write heavy OOP code. Writing ease(target).to(..) looks like a hack to me… but maybe i just have to get used to it… and get rid of my lower / case uppercase purism.

  3. cool thing, if only those plain objects could be class instances. plain objects do not allow auto-completion and i figured, that’s what you wanted to achieve as one goal.

  4. Marcin,
    this change is to avoid the static VS instance conflict of to/chainTo methods. And I’m very happy with it 🙂
    I don’t think it’s a hack – it’s just that we are used to see AS2 and Java without this kind of functions.

    Mark,
    I’ll check your sample, maybe you found a chaining bug.

  5. Great job Philippe! I have been using Eaze for a little over a month and I love the syntax and simplicity of your library. It’s nice to know it performs as fast as engines like BeTweenAS3 and TweenLite even though I’ll never tween 20000 objects simultaneously, ever 🙂 I was a big fan TweenLite but the licensing model bothers me. I then adopted GTween, but it had its limitations. Now I am considering Eaze or BeTweenAS3 as my primary tweening engine. Chances are I’ll use Eaze for most projects and BeTweenAS3 when the requirements are more complex. Please let me know how I can make a contribution. I wouldn’t mind making a donation to support your efforts.

  6. I’m really digging the syntax of this library. I’m having some wierd results though. Maybe I just don’t know what I’m doing however:

    eaze(shape).to(1, {x: 100, y: 100})
    .onComplete(onComplete1)
    .to(1, {x: 200, y: 200})
    .onComplete(onComplete2)
    .to(1, {x: 300, y: 300})
    .onComplete(onComplete3);

    In my complete functions I’m just basically tracing the position of shape.

    My shape will tween to 100, 100 and then call onComplete1.
    Then it will tween to 200, 200 and then call onComplete3 and then the tweening is finished.

    I’m expecting it to go:
    100,100, onComplete1
    200, 200, onComplete2
    300, 300, onComplete3

    OR is my thinking wrong.

  7. Also I’ve done the following:

    eaze(shape).delay(1)
    .from(4, {x: 100, y: 100})
    .updateNow();

    For some reason my sprite starts at 0, 0 not 100, 100.

    I’ve also tried the following:
    eaze(shape).delay(1)
    .from(4)
    .filter(BlurFilter, {blurX: 100, blurY: 100})
    .updateNow();

    And basically it works but does not do the updateNow. So the object does not start blurred.

    I hope I’m just really using this library wrong. Please please tell me I’m an idiot and I’m using this wrong AHAHAHA.

  8. Hi,

    thanks for your great work..

    I’m using r58, still get the bug with .onStart – It won’t trigger if delay is 0

    Of course you may think that we can call that onStart function directly but it’s not the case. I want it to be executed in next render (delay = 0) but render on start… or maybe i’m in a loop that the delay depends on the id of item (item at id =0 should start animation right away)…

    Thanks.

  9. Pingback: PPZhu-Blog - ????

  10. Hey Philipp,

    Really enjoying your library so far! Feels better to code than tweenlite

    While using it I noticed eaze has abit of funk with overrides, Im tweening multiple properties (x,y, scaleX, scaleY from seperate events) on the same object setting override to true/false in various combinations – I couldn’t really get the effect I was looking for.

    For instance setting all the tweens override to false, i get the desired effect, almost, I have a mouseover/mouseout on multiple objects, hovering over them all fast they all seem to ‘jump’ to the end.

  11. thienhaflash,
    That’s right, onStart was not fired when the tween has no delay – fixed in SVN r59

    Jarrad,
    Override handling did not honor overridden tweens in the right order – fixed in SVN r60

  12. Hey the good tween Author !!
    I have saw this project in a site and fall in love with this fantastic
    work ! However in this moment i am not yet ready for comment
    about the use , because i am just now tring to use , just give the
    thanks , see u

  13. Pingback: ??LuoYe » Eaze, ????????? Flash???? Flash???? AS???? flash?? PHP MYSQL

  14. It’s actually a bug, though it’s a bit hard to find a reasonable case to use, man…

    It seems to be foolish having a movieclip chasing the mouse that way, of course, it’s just a dummy sample. Let me introduce another sample, a better (more complex) one…

    Let’s assume that you have a virtual mouse which is moving around by code, and this virtual mouse can be changing its position each frame (maybe someone is tweening it). Each time the virtual mouse move, its dispatch an event and another movieclip (A) is listening to it. (A) need to tween to the virtual mouse’s position (which can be changed abruptly, and we don’t want (A) to change the position abruptly ). Because the virtual mouse sends the MOVING event each frame, then the onVirtualMouseMove handler just be called each frame, then the eaze.to is called each frame, hopefully it will overwrite the previous one to keep (A) aiming at the virtual mouse… but it’s not – until the virtual mouse stops moving which can be long (some seconds, or what if the virtual mouse keeps moving ? )… and for these some seconds, the movieclip (A) just sit there doing nothing…

    There are other cases i got this problem while developing things… but it’s rather complex trying to explain here…

  15. Thienhaflash, I perfectly understand what you want to do. I’ve programmed this kind of animation many times since I started in Flash 5!

    You’re not the first person to try using a tween engine for that but it is a misunderstanding of how tween engines work. Show me another tween engine where this is possible to prove me wrong.

    “Hype” is a good fancy animation framework with a mouse follow behavior:
    http://hype.joshuadavis.com/02_examples/mousefollow/02_mousefollowease/

  16. “Oh and according to Jack “TweenLite/Max” Doyle’s tweening speed test, Eaze is the fastest library around. Yep.”

    hmm, I clicked the page but didn’t find Eaze in the tests

  17. hey , i like this update news and don’t u guys think to export a version of swc for
    us to use more easy ? just like Eaze = Easy 🙂

  18. Pingback: Eaze, ????????? | ? ? ? ?

  19. I’m sorry but at least for what i remember i can do that thing with TweenLite (i used tweenlite a lot 2 years ago when there is still no TweenMax and others…)… haven’t checked with other engine yet but i’m pretty sure that a tween engine should be implement this way, I myself worked a lot with testing / developing tween engine also on daily basis …

    I can do mouse follow stuff, too, man. And It’s not the actual problem anyway…
    I know i can add an Event.Enter_FRAME, then within the handler, just set
    mc.x += (stage.mouseX-mc.x)/10;
    mc.y += (stage.mouseY-mc.y)/10;
    and for this case we don’t need a tween engine

    Let’s consider another sample. You have a container, when user click on that container the content changes with tween (the old content move out, the new content move in). What if the user click too fast ? with eaze the images just stuck there or moving slowly / abruptly until they stop click…

    Of couse we can disable mouse until the tweening is fully completed, of course there are other ways to get this kind of thing done but it’s not the easiest/simplest way…

  20. Works great 🙂 I tried some basic stuff and didn’t had time to look at some big features i’d love ; as i’m about to “migrate” from TweenMax to Eaze (since it looks easier, smarter and french :D) my questions are all in reference of what i know (this may sucks to compare but…) :

    Do you have kind of killTweensOf / killChildrensTweensOf ?

    Is it possible to have an “allTo” with a “stagger” property to easily chain tweens with an internal delay (anyway this could be done with a loop but if it’s in the box, i feel better :D) ?

    Thanks a lot !

  21. @y_nk:
    Currently you have to use EazeTween.killAllTweens() / killTweensOf() – I plan to make it more natural eventually.
    Some kind of multi-tween could be done – will think about it 🙂

  22. Hi again ; I’m still testing your api and find some features to talk about.

    1/ It would be cool to see relative coordinates with special cast :
    eaze(target).to({ x:”100″ })

    It would say something like “x += 100”, helping games or other interactive projects.

    2/ I just started to understand what linkedlist are, and how powerfull they can be. As you write eaze tweens like “chaining” function calls, i thought you could have built eaze with linkedlist ; so i started to think about accessing to “previous” and “next” nodes and finally thought i’d love something like this :

    eaze(target).forward(2).to({ x:”100″ }).backward(2);

    Those “forward” and “backward” utility functions would be able to control the way the tween goes, with counting how many time they’ve been called. This tween would shake the target 2 times from left to right with increment of 100 (which could be relative too). Also, without parameter it could be endless 🙂

    In extension you could do an other utility function :
    eaze(target).to({ x:100 }).repeat(2, true); with .repeat(times:int, reverse:Boolean);

    I started to write some eaze tweens with and without those features :

    Before :
    eaze(target).to({ x:target.x + 100 }).to({ x:target.x – 50 }).to({ x:target.x + 100 }).to({ x:target.x – 50 }).to({ x:target.x + 100 }).to({ x:target.x – 50 });

    After:
    eaze(target).forward(4).to({ x:”100″ }).to({ x:”-50″ }).backward(3)

    Well i’m tired now. Hope u’ll like this idea. I just wanted to help 🙂

  23. It’s not possible to create simultaneous tweens ate the same time on the same object?

  24. Paulo, it is definitely possible to create simultaneous tweens on one object:
    eaze(target).to(0.3, {…});
    eaze(target).to(0.3, {…}, false/*do not overwrite*/);

  25. Thank you Philippe.
    I like eaze tween a lot, good work.
    I’ll use it on the next project.

    🙂

  26. Brilliant work!! Minimalistic to the extreme!! The syntax is strangely intuitive once you get the hang of it :). I am currently using your nifty engine in a project of mine.

    However I hit a snag.

    As a part of a render loop I tween a bunch of objects around the screen in response to user interaction. Now I have a fixed number of objects and thought it would be efficient to create a fixed number of EazeTween objects and simply reuse them by calling the to() method and just reset the values of the parameters I intend to tween.

    Everything tweens fine on the first iteration. But after following that any attempt to reset the values results in the following error:

    [Fault] exception, information=ArgumentError: EazeTween: target can not be null

    So I did a little digging and it turns out that EazeTween instances call a private dispose() method that sets the target reference to null. I noticed that the to() method has an overwrite parameter which I set to false but the target reference is still set to null in the code…Any other work arounds?

  27. @Damion
    Tween objects are not meant to be kept around: each time you use .delay, .to, .from, .chain, a new EazeTween object is created (and disposed when done) – this is how it is designed.

  28. But isn’t object creation a costly operation? I’ve read somewhere that it’s more efficient to reuse objects where possible instead of instantiating new ones. How about maintaining a pool of tween objects and recycling them. I think I’ve seen a tween engine implement something of the sort. May speed things up a bit. Not that I’m an expert or anything…

  29. @Damion: reusing objects is good but it’s up to the library to handle it internally: it could be implemented in Eaze without you having to worry about it. It was even initially implemented in Eaze but didn’t seemed to have a big impact so I cut it.

    But I keep that in mind, especially considering the need to be extremely lightweight for mobile – I may even trade some performance to reduce the library complexity and memory impact.

  30. I’ve been using Eaze/eaze in the 6th project now and it really makes my day. It’s fast, reliable and easy to use. Would love to have swc’s for download that I don’t have to package them myself. But that’s just a minor wish. Thanks for the great job! Absolutely recommended.

  31. Cool…but please don’t sacrifice performance for anything if you can help it…

  32. I’ve been using Eaze for a while now and I absolutely love it. Thank you!

    One question though is it possible or will there be a way to check if object is tweening? Or how to avoid creating new tween (onEnterFrame, onMouseMove or whatever) if the object is tweening? Otherwise objects look jerky while tweening.

    For example:

    function onMouseMove(e:MouseEvent):void {
    eaze(mySprite).to(.25, {x: 100});
    }

    Object will stop before continue every time mouse is moved. And it seems like “overwrite” property set to true or false is not helping.

    Any advise?

    Thanks

  33. I’ve managed to create a simple isRunning read only property inside EazeTween class and it works for me so far. Need to test it a bit more though.

    public function get isRunning():Boolean
    {
    var v:Boolean = false;
    if (running[target])
    v = true;

    return v;
    }

  34. oh,this really great man.Chaining all the stuff together is cool,although IDE (like FDT) doesn’t give me code hints when chaining.
    Anyway,I think it’s necessary to make a swf listing all the features,examples.And more document please..

    Thanks~

  35. @MorrisLiang
    – I’m pretty sure FDT/FlashBuilder should perfectly support Eaze chaining & stuff.
    – Examples can be found in the SVN.

  36. Merçi philippe , je vien de jouer un peux avec,j’ai quelque questions:
    1)On peux acceder a “inst” ds : var inst:EazeTween=eaze(mc).to(2, params)?
    2)Exist-il une façon de faire comme ça : eaze(mc).puase() et apres eaze(mc).continue()
    3)comme on peux savoir si une instance de EazeTween est en marche maintenant ex:
    for( i in aray_instans_eaze)
    if(aray_instans_eaze[i].isMoving())
    trace(aray_instans_eaze[i])

    en tout cas un grand Bravo pour ton travail 🙂

  37. Can’t figure this out how to remove Glow filter

    eaze(target).to(duration) .filter(GlowFilter, { blurX:20, blurY:20, color:0x00ccff, knockout:true });

    to remove i try the GlowFilter,

    eaze(target).to(duration).filter(GlowFilter, { blurX:0/null, blurY:0/null});

    but i am sure the Glow prop is not been dispose

  38. @toto
    // add ‘true’ to kill filter once tween is done
    eaze(target).to(duration).filter(GlowFilter, { blurX:0, blurY:0}, true);

Comments are closed.