Introducing caurina.transitions.Tweener

In 2003, I was pretty pissed with the tweening extensions available at the time. I found them to be too clumsy and overly complex, requiring a lot of code just to create a single transition. I didn’t want to use 3+ lines just to change the way a button looked like when it was rolled over. After giving up on the task to find a simple extension based on Robert Penner’s equations, I decided to create such an extension for my own use. Called MC Tween, it was very straightforward; it didn’t create instances, didn’t allow you to rewind anything, nor did it allow you to create then fire animations separately. And in fact, it didn’t intend to; it just created a simple tweening, played it on the specified time, and called it a day.

To my surprise, it quickly got bigger than I expected when everybody started using it at my workplace, and then when it became the most popular prototype on good old proto.layer51.com with no “marketing” whatsoever. It didn’t even have any documentation, all I used to say was “look at the source code, the methods are there”. MC Tween evolved a lot on the following years, getting a small website of its own (one with proper documentation!), and getting really popular with some folks. I still receive email about it almost everyday, and I like to believe it was the first of its kind – using simple code to create tweenings in a fast and straightforward way, inspiring designers and programmers alike to stop using the timeline and adopting code-based tweening almost exclusively.

With that said, well, I have something to confess…: I haven’t been using MC Tween for more than one year, including on all my commercial work.

The reason is, I’ve been slowing developing a new tweening thing. Now, instead of a collection of prototypes that extend the existing classes by way of AS1 code and AS2 hacks, it’s a real static class, working the same way on both AS2 and AS3. And while it still follows the concept of simple, one-line tweenings, it’s has a slightly different syntax. It’s called caurina.transitions.Tweener, or just Tweener.

Now, to be honest, there’s still a bit left to go for Tweener to have as many features as MC Tween has. For example, Tweener doesn’t have native filter tweening, as we’re still deciding on the best syntax approach. However, at the same time, there’s a lot of positive things about Tweener, and because of this, I feel it’s about time Tweener is publicly announced. So there it is. I don’t work with MC Tween anymore, and I won’t change it anymore. It was a good extension, and it still is, but I have thought a lot about code-based tweening for the past 4 years and I have reached the conclusion that there’s a slightly better approach; that’s what I think Tweener is.

Did you notice I said “we’re still deciding on the best approach” above? Yeah, it’s because Tweener is more like a group affort, differently from MC Tween, which was mostly a one-man job, taking suggestions from here and there. Currently, Tweener is being helped by Nate Chatellier, who wrote the original AS3 version and has been providing valuable input on both versions, and Arthur Debert, which has helped with submitting bugs and fixes as well as suggestions on how stuff should work.

Anyhow, there’s a lot I could say here but I would probably just be repeating myself. So if you’re interested, Tweener is available for anyone who wants to test it. Its official page is hosted at Google Code. You can download the stable version, or download the latest versions, available from Subversion, or from the web version of the repository. You can also check the changelog. And if you want to see it in action, there’s a few examples available; this time, I’m trying to make examples as distinct as possible, covering as many different development setups as possible. Right now, there are examples available for AS2 under Flash 8 and MTASC, AS3 under Flash 9, and Flash Lite 2 under Flash 8, but I expect to add more as time allows.

The documentation is still being written but there’s plenty of content already. If you’re a MC Tween (or similar) user, you can check the differences between MC Tween and Tweener – it explains the new class in depth and also has a few bits on the rationale behind most of the changes.

And finally, there’s a discussion list for generic Tweener discussion (in english).

Wew. It feels good to finally get that off my chest. So there.

54 responses

  1. Thanks Zeh! MC Tween has really made my job a lot easier and I can’t tell you how many hours of time you’ve saved me. I feel confident that this new extension blows the doors off MC Tween and will saved me countless hours. You’re the best!

  2. Great news…
    I’m a long time mc_tween user..
    Coincidentally I just struggled today with some issue with mc_tween usage within a seriously more object oriented project with tons of custom classes.
    and.. tweener is there just in time, can’t wait to test it. 🙂

    quick question: colorTransformTo already ported in tweener ?
    and how would it translate ?

    Many thanks again for your contribution.
    My flash dev would not be the same without mctween.

  3. Thibaud: thanks!

    The method colorTransformTo() itself isn’t available. Tweener doesn’t feature shortcut methods like MC Tween did. However, it does allow you to use ‘special properties’ to create some special tweenings that are not directly related to numeric properties. On colorTransform’s case, the property would be _colorTransform, or _color, or the individual properties: _color_ra, _color_rb, _color_ga, and such. For example, to apply a colorTransform object,

    myColorTransform = {ra:100, rb:0, ..etc..};
    Tweener.addTween(myMC, {_colorTransform:myColorTransform, time:1, …});

    Or (tinting)

    Tweener.addTween(myMC, {_color:0xff221e, time:1, …});

    Or (specific properties of a colorTransform)

    Tweener.addTween(myMC, {_color_ra:100, _color_rb:0, time:1, …});

    Or (resetting to normal untinted color)

    Tweener.addTween(myMC, {_color:null, time:1, …});

    There are also changes from AS2 to AS3, however. Color changes use different values on AS3 (0 to 1 instead of 0 to 100 and so).

    Granted, I haven’t wrote this part of the documentation, but it will be available soon with the list of special properties it has by default. Also check the “SpecialPropertiesDefault.as” for a list of the available special properties. There aren’t many, because the idea of Tweener is to allow you to directly tween some properties (including specific matrix properties, soon) instead of creating a new particular syntax based on a lot of custom special properties that one would have to remember.

    It also allows people to create new special properties by way of some functions that work like getter and setter methods, which grants users the ability to ‘customize’ tweener to their heart’s content. This is also other of the big features of Tweener compared to MC Tween. So it’s possible to create real Tweener ‘extensions’ that add some specific functionality, like for example color transformation similar to photoshop using specific properties (hue, sat, brightness, contrast, etc) instead of just raw changes to the color transformation matrix. More on that when I write that part of the documentation (god I hate to say this all the time…).

  4. s.barret: I wouldn’t know, as I haven’t tested it much. For me, it’s easier to compare it to MC Tween since that’s what I’ve worked on for years.

    I’ve talked to Moses around one year ago when he told me about his plans with Fuse, and syntax-wise, we had reached more or less the same conclusions (using a static class and such). So in the surface they might be a bit similar; I can’t say for sure.

    If this helps, there’s one different design rule I’ve taken with Tweener though – to do things as simple/straightforward as possible and in one way only. There’s only one syntax, only one approach (save for creating variables themselves differently), one way of including the class, etc. This is either good or bad depending on who you’re asking.

    Both serve the same purpose in the end, so they’re just slightly different tools for roughly the same job. My stance with different tweening extensions/classes have always been that people should use the one which has the syntax they like the most, and in many ways this is highly subjective, so I don’t think I could ever do a fair comparison between Tweener and any other similar extension, Fuse included.

  5. Congrats Zeh! As a long time user of mc_tween (I did my first project with it back in fall of ’03), it’s great to see it grow. I know when Flash 9/CS3 comes out I’ll be upgrading my tween code to use Tweener along with the rest of the AS3 stuff in the new app.

    Again, as someone who uses mc_tween ALOT and a frequent commenter on your page at proto.layer51, thanks so much!

  6. Congrats Zeh! Very exciting to *finally* hear an official announcement! 🙂 Having been a long term user of MC Tween myself, when I asked Zeh if there was an AS3 version many months ago and he told me about Tweener, I was eager to start using it immediately. Having used both extensions extensively, I definitely prefer Tweener over MC Tween. Especially in the AS 3.0 world where OOP programming is a necessity. Thanks Zeh!

  7. Olá Zeh,

    I’ve been searching for an easier way to do tweens in AS3. I came across one or two interesting aproaches for tweening in AS3, but it was a big surprise when I discovered Tweener. I’ve always used Fuse in my AS2 projects, so I cannot compare Tweener to MCTween. I can however say that from what I’ve seen, the Tweener syntax is similar to the one I used in Fuse with the difference that in Tweener all tweens run simultaneously by default while in fuse they run one by one, in sequence. I really miss this behaviour in Tweener. Anyway thanks alot for releasing this great piece of software, I’ll be following it closely.

    Obrigado!

  8. Tiago: I think I overlooked that on the documentation. Anyhow, the idea with Tweener, as it was with MC Tween, is that you can create sequential tweenings by explicitly delays. For example, to make a movieclip go to _x = 100 then _x = 0 again:

    Tweener.addTween(mymc, {_x:100, time:1});
    Tweener.addTween(mymc, {_x:0, time:1, delay:1});

    So it’s possible to create ‘sequences’ of tweenings on the same object that way.

    There are positive and negative reasons for both approaches – auto ‘sequencing’, or delayed tweening – but personally I prefer to make the delays explicit and that’s the approach Tweener takes.

    I’ll make that easier to figure out on the documentation.

  9. spot on man, good to see things evolving. As for Fuse, I’ve looked into it, and a lot of it seems overkill. The sequencing engine is a good idea, but if I want complex animations that are sequenced I think I’ll just stick to frames.

  10. Thank you for your important contribution to the WEB upgrade. Its much more animated since your MCTween has been invented. Whish you luck whith your next-gen release.

  11. Hi, excited to experiment with the new class.
    Bit of a hack with the mcTween, though I’m still learning.
    Question, is there a significant file size difference between projects built with MCTeen and the new tweener method. Do you expect file size to change as the class gets further optimized?

    Thanks again,
    -greg

  12. Greg: there is a difference, although not very significant from most points of view: including the most recent version of MC Tween takes 7.9kb of the SWF; importing Tweener takes 9.5kb of the SWF.

    The changes from now on Tweener will be minimal, but it’s safe to say the size will increase as more features get added, little changes are made, and new special properties are created. I’m guessing that after the planned features get added, Tweener will take 11kb-12kb of the SWF.

    Optimizations themselves make the code faster and ‘more intelligent’, but usually not smaller (unless there’s a lot of byte overhead caused by unneeded code). In that aspect, I don’t think there’s a lot to be changed on Tweener.

  13. Hey nice work, I was equally frustrated with the early Tweening extensions and came up with my own simple class in ’04 called… Tweener! – don’t worry I won’t enforce the copyright 🙂

    You can see it here http://blog.vixiom.com/2007/01/12/scripting-animation-in-actionscript/

    It uses an ‘addTween’ method as well to chain things together. I’ve been using it ever since but may switch to your Tweener as some of my early hackery still remains in mine , the way you add properties in yours is more elegant and the ‘right’ way to do it.

    Quick question: you use onEnterframe rather than an interval for running it, does that give better performance?

    If I can throw my two cents in whatever you do keep it as simple as possible, engines like Fuse Kit are great but they have a steep learning curve for the non-programmers (and even some programmers).

  14. Wow, Alastair. What the hell? The resemblance in the “Tweener” and “addTween” name are striking, even if the syntax is different everywhere else…

    Well, first of all, sorry. I knew the name was quite generic and I did look around for similar classes trying to find some one with a similar name that would prevent me from renaming my own, but I didn’t find any, and that’s why I picked this one (just out of curiosity, originally it was called “ZTweener”, then “Twina”, then I finally decided to go for the basics and settled with “Tweener”).

    Second of all, thanks for not enforcing it. This is as frustrating for you as it’s for me, I’m quite sure…

    About the onEnterFrame/interval debate – this is an old debate and one that can create a long discussion, but the conclusion is that, *performance* wise, both are similar, but *result* wise, onEnterFrame is much better because it syncs updates with frame rendering — so you will always get 100% correct updates, no matter when you do it. With intervals, you’d have to be shooting for some crazy frame sync to be able to match onEnterFrame’s updates, and it could easily skip frames. That’s the biggest issue; intervals are not even a valid option on face of that.

    I say this because MC Tween (Tweener’s “older brother”) originally used intervals, and after many many tests I came to the conclusion onEnterFrame is, by far, a much better approach… it’s the only correct approach. Again, not because of performance (that’s just of secondary importance on this comparison), but because its updates are much, much more precise.

    There is a big parenthesis that needs to be drawn here, though. On AS3, the VM renderer is able to visually update items at a different framerate, something that you couldn’t force on AS2 before (except for updateAfterEvent() which was not really the same).

    This means that while you can have, say, 30fps on your movie, you’re still able to update certain specific elements by, say, 100fps. On this case, control is done by intervals, and it IS synced to frame drawing (elements are rendered on screen as they are updated) so you wouldn’t have this syncing problem. This means that, on AS3, both approaches are pretty much the same; onEnterFrame will be better for a robust tweening engine because you can have a central control of all your tweenings, meaning there’s just a single loop that updates everything.

    With intervals you would have a bunch of different functions firing at different times, so it’s not very elegant; however, it would be barely noticeable, if ever (I predict you’d need at least half a thousand different tweenings to even make the AS3 vm lose a few frames due to tweening code).

    Flex’s Tween clases use this interval approach, which is actually a good idea and something that will be implemented in the AS3 version of Tweener in the future (with the ability to set the FPS directly instead of using the default movie FPS which is onEnterFrame-bound). It’s something that should be used sparingly (having many different framerates on a movie could be an issue for the user), but still a positive feature for some specific cases.

  15. Hey Zeh, it’s obviously a coincidence with the similar names, and now I’m already preprogrammed to use addTween with your Tweener, one less thing to remember 🙂

    Thanks for the explanation on onEnterFrame vs Intervals, I didn’t know about the syncing issue.

    All my new projects are AS3 so I’m looking forward to final AS3 version.

  16. Hi everyone:
    Tweener is great, but I have some problems to install it, when playing with docked_icons_as2_flash8
    When I include the path ‘E:\workspaces\flashspace\misc\docked_icons_as2_flash8\classes\caurina\transitions’
    or ‘E:\workspaces\flashspace\misc\docked_icons_as2_flash8\classes’ into the flash, it won’t compile and it says Tweener.as can’t import Equations.as

    I am using flash 8 pro
    any idea?

  17. Gary: no clue; that example (as all examples provided) should work out-of-the-box even if you don’t have Tweener installed. You don’t even need to include any classpath into your settings, since that specific .FLA already uses “./classes” as its class path and Tweener comes on that folder.

    (It’d never be “…\classes\caurina\transitions” by the way, you have to use the top class folder)

    I’d only suggest you making sure you have the latest Tweener version installed (or no version at all as long as you use the included .as files), that you extracted the .zip file with folders intact, then open the FLA document and select “Control” > “Delete ASO Files and Test Movie” from the Flash IDE menu to skip class caching.

  18. Following my previous post, I pasted the actual error here, hopefully someone may have an idea for this:

    **Error** E:\workspaces\flashspace\misc\sliding_icons_blurred_as2_flash8\classes\caurina\transitions\Tweener.as: Line 32: The class or interface ‘caurina.transitions.Equations’ could not be loaded.
    import caurina.transitions.Equations;

    Total ActionScript Errors: 1 Reported Errors: 1

  19. Hi ZEH I’m a long time mc tween user and I will be of TWEENER new class, thanx so much this is really powerfull.
    I love you so much thanx man.

  20. HI Zeh!

    How I can call the function inside some function when animiation is complete, I try but I cant.

    function someName(){
    function someFunction(){
    trace(“HI Tweener”)
    }
    Tweener.addTween(mc, {_x:100, time:1.0000, onComplete:someFunction, transition:”linear”});
    }
    someName();

    I try use this but no result??
    I can only call function which is out of scope function someName(); it’s true???

  21. Hmmm sorry my big mistake. The Problem was that, before Tweener I had one if else statement and function which I want to call when transition is completed, was inside if statement.
    Example:

    function someName(name_:String) {
    if (name_ != “zeh”) {
    function someFunction() {
    trace(“HI Tweener”);
    }
    Tweener.addTween(mc, {_x:100, time:1.0000, onComplete:someFunction, transition:”linear”});
    } else {
    trace(false);
    }
    }
    someName(“mike”);

    But someFunction must be before if else statement or after:

    function someName(name_:String) {
    function someFunction() {
    trace(“HI Tweener”);
    }
    if (name_ != “zeh”) {
    Tweener.addTween(mc, {_x:100, time:1.0000, onComplete:someFunction, transition:”linear”});
    } else {
    trace(false);
    }
    }
    someName(“mike”);

    That was problem.

    SORRRRYYY ZEH I dont want fill this page with stupid and unseless questions and comments.
    Sorryyyy..

  22. Hey Mila,

    No problem asking questions, but really, next time use the mailing list. It’s much better for discussion and doesn’t fuck up formatting, plus there are other people there who can help.

    Anyhow, on your case, the problem is not with Tweener but with the way you’re declaring your functions. Try this:

    function someName(name_:String) {
    	if (name_ != "zeh") {
    		function someFunction() {
    			trace("HI Tweener");
    		}
    		trace ("someFunction is: " + someFunction);
    	} else {
    		trace(false);
    	}
    }
    someName("mike");
    

    The output will be:

    someFunction is: undefined
    

    That is, Tweener won’t even have anything to call, the function doesn’t exist.

    If you’re working on the timeline, generally it’s a bad idea both declaring your functions on the middle of the code, and specially with the “function” keyword. The function whatever() {..} block is a bit of a legacy hack in actionscript – basically functions aren’t declared during the block, but after certain specific blocks of code are done.. after your IF on your case, so no code you put there will be able to refer to the function itself.

    In sum, instead of this:

    function whatever() {
    }
    

    Use this for temporary/timeline functions:

    var whatever = function() {
    };
    

    Or this for explicitly declared timeline/object functions:

    this.whatever = function() {
    };
    

    So this works, notice I’ve just changed the function declaration:

    function someName(name_:String) {
    	if (name_ != "zeh") {
    		var someFunction = function() {
    			trace("HI Tweener");
    		}
    		Tweener.addTween(mc, {_x:100, time:1.0000, onComplete:someFunction, transition:"linear"});
    	} else {
    		trace(false);
    	}
    }
    someName("mike");
    

    So I really recommend you not using “function whatever() {…})” on timeline function declarations.

    If needed, it’s also a good idea to use simple, anonymous functions on Tweener instead:

    Tweener.addTween(mc, {_x:100, time:1.0000, onComplete:function() { trace("HI Tweener"); }, transition:"linear"});
    

    Or even:

    Tweener.addTween(mc, {_x:100, time:1.0000, onComplete:function() {
    	trace("HI Tweener");
            // other lines of code...
    }, transition:"linear"});
    
  23. I faced the same problem of loading Equations class with

    import caurina.transitions.Tweener;

    I open the Tweener.as and Equations.as. Touch them and save again. Then flash complie it without any errors. I don’t understand what had happened but it’s really strange.

  24. Hey zeh,

    First I would like to thank for sharing MC_Tween and Tweener freely with everyone. They are really great tools and I have been using MC_Tween for a long time. Now I decided to switch to Tweener. But I actually encounter the exact problem gary mentioned (problem loading Equation). I was wondering whether this is a common thing most people have or it’s just because I did something wrong (which I don’t know). 🙁

    Thanks,
    Frank

  25. Frank: that shouldn’t happen as long as all the files are correctly used on the same dir.

    If nothing works, post about your specific case on the tweener discussion list so it’s easier to discuss it.

  26. zeh,
    thank you wonderful Tween MC, I meet a problem, please help me.
    when I use Array.prototype.xxx, the callback will not work.
    Array.prototype.addin=function(){
    this.push(arguments[0]);
    }
    box.tween([“_x”,”_y”,”_xscale”,”_yscale”],100,100,10,10],1,”easeOutCubic”,0, myCallBack);

    function myCallBack(){
    box.colorTo(0xff0000,0.1);
    trace(“ok”);
    }

    David

  27. David, using Array.prototype breaks actionscript in a number of ways (mc tween included) because a for..in won’t work anymore inside arrays. You have to properly hide the new function by using ASSetFlags. The same is true to any method of any prototype you extend.

    ASSetPropFlags(Array.prototype, “addin”, 1, 0);

  28. Good one, but no.

    As mentioned on the documentation, “caurina” isn’t supposed to mean anything – it’s used just a random name to keep the class path unique. It’s based on the name of my own company, “caurinauebi”.

    Originally, the classpath was “zeh.transitions.*”, but since this is a group effort (as Nate Chatellier and Arthur Debert are also on the Tweener team), it doesn’t make sense to have just my name on it, so it was changed for something more innocuous.

  29. Zeh, I have exact the same problem as gray did… Still do not know how to fix it. I found the examples in as2 having this problem while those in as3 works just perfectly.

  30. and weird enough, if you open the Equations.as and edit it a bit…just type anything not relevant then save it again. Now it would work…

  31. This sounds like a problem with Flash class cache, so I don’t think there’s anything that can be done on the source files themselves (that is, anything I could do). I’d recommend using the “Delete ASO files and test movie” compile command first.

  32. yeah…I tried delete ASO files and test movie…it did not seem to work.
    anyways, thanks a lot.

  33. I have encountered a Fatal problem of MC_Tween.as . Please kindly comment.

    The case is I could not include the MC_Tween.as file. I have follow your instruction, checking the correct folder, and everything are correct. However, the Flash CS3 complier always say that ” can’t include the MC_Tween.as file in the swf. I am using as 2 script.

    This make me frustrated a lot and please kindle help.

  34. Try using

    #include “mc_tween2.as”

    Instead. If that fails, the file simply isn’t on an acessible folder. Either install the MXP file on the correct version of Flash, or unzip the file on the .fla folder.

  35. first, sorry by my English…

    I try to apply blurTo to a mc with an image inside… work with images (or mc) when the width is less than 2700 pixels, my mc (with 3 images inside) have 3000 and don´t work.
    Note: if a move one image (and the total width of the mc is less than 2700) work.

    Any idea?
    Regads.
    Leo.-

  36. I have to say MC Tween is amazing. I really like the animation start delay feature. I cannot explain how usefull is this to me. Great job !
    Looking forward for the Twenner class.
    Regards,
    Adrian

  37. Hi All,

    I am trying to install the MC Tween extension to my Flash 8, however, I keep getting an error stating that the extension requires Flash MX or greater. The description under downloads does state that Flash 8 is compatible with this extension, or vice versa. What am I doing wrong?

    Thanks for your help!

  38. Bram: I don’t know. MC Tween is perfectly compatible with Flash 8.

    If you have more than one version of Flash installed, be sure to select the correct version on the combo.

    If that doesn’t work, try re-download adobe/macromedia extension manager.

    Other than that, I have nothing more to say. It should work.

  39. Zeh, beleza?

    Então cara, estou usando a classe Tweener e vi um possível problema. Eu tenho um movieclip (container_mc), onde dentro dele existe um outro movieclip com blend mode setado dinamicamente, para screen. Quando eu adiciono o tweener no container_mc, com _blur_blurX, o blend mode do movieclip interno se perde. Você tem alguma idéia do porque isso acontece?

    Abraços e parabéns pelo excelente trabalho.

  40. Oi Felipe,

    Cara, isso é meio que o esperado. É ruim, mas se trata da maneira como o Flash renderiza camadas.

    Quando você usa um blendMode diferente, ele tem de levar em consideraçao o que está atrás separadamente. Quando você aplica um filtro (ou cacheAsBitmap), você força um container a “se renderizar” internamente e só após ser aplicado sobre o que está atrás. Se dentro do container você tem blendingModes diferentes, eles se perdem na hora da aplicação final porque não tem como o Flash aplicar blendingModes diferentes “por pixel” de cada container.

    Já que não é uma questão de Tweener, não tem muita solução, sinceramente. A sua solução vai ser bem customizada e depende muito de como a coisa funciona. Um jeito é aplicar o blur em todos os containers filhos (todos os mcs dentro de container_mc), não no container pai (container_mc). Outra solução é o container pai (container_mc) ter o mesmo blendingMode do container filho, mas aí depende se o resto do conteúdo dele pode usar o mesmo tipo de blendingMode sem modificar o gráfico.

  41. I have the Tweener import code in the first frame of my main timeline, and am able to animate movieclips that are also on my root timeline, however when place the Tweener.addTween… code in a nested movieClip and try to animate movieclips on that nested timeline nothing happens… can you think of why this might be?

    Thanks!

  42. Thanks… Believe it or not, I read that previously. Not closely enough, I guess.

  43. Caro Zeh, tudo bem? Estou com uma dúvida, pois sou iniciante em as3. Fiz um swf principal que chama outro swf (loadMovie(“photo_gallery.swf, _root.mc_vazio). Este swf com Tweener nao carrega com suas funçoes e nao trabalha. Voce poderia me ajudar?
    muito obrigado e parabens pelos seus trabalhos.
    Renato

  44. @Renato: deveria funcionar. Já usei subfilme com Tweener e rola. Lembre-se de que o import é necessário sempre que uma classe é usada, em todo frame/filme/movie que a usa.

  45. Zeh, boa noite!

    A classe MC Tween 2 é compativel com o Flash CS4?
    Quando publico meu filme ele não encontra o mc_tween2.as, tem alguma idéia do que pode ser? obrigado e um abraço!

Comments are closed.