GreenSock


TweenFilterLite (AS3 Version) - Easily Tween Filters & Image Effects

Posted in Tweening by jack on the October 18th, 2007


Version 7.12, Updated 4/27/2008


Download Now
 
Donate

Join Club GreenSock to get updates and a lot more

RECENT VERSION HIGHLIGHTS

  • IMPORTANT: syntax change! - instead of defining a "type" property that indicates the kind of filter, you define a property like "blurFilter", "glowFilter", "colorMatrixFilter", "dropShadowFilter", or "bevelFilter" and pass an object with whatever properties you want to tween. So

    OLD SYNTAX:
    TweenFilterLite.to(mc, 2, {type:"blur", blurX:20, blurY:20, delay:1});

    NEW SYNTAX:
    TweenFilterLite.to(mc, 2, {blurFilter:{blurX:20, blurY:20}, delay:1});

    Why make this change? Here are a few reasons:

    1. It allows you to tween multiple filters with a single call, like:
      TweenFilterLite.to(mc, 2, {blurFilter:{blurX:30}, colorMatrixFilter:{colorize:0xFF0000}});
    2. It eliminates problems with ambiguous properties like "alpha". Some people wanted to be able to tween a Sprite's alpha property AND a DropShadowFilter on that Sprite with the drop shadow's alpha changing too, but with the old syntax, you could only define one alpha
    3. It makes it more flexible to extend (e.g. my upcoming TweenMax class)
  • Removed DisplayObject limitation: - Previously, TweenFilterLite only allowed you to tween DisplayObjects, but you can now use it for any object. It is still recommended that you use TweenLite directly to tween non-DisplayObject because it'll perform slightly faster, but unless you doing a LOT of tweens simultaneously, you'd probably never notice a difference.

DESCRIPTION

TweenFilterLite extends the extremely lightweight (about 3k), powerful TweenLite "core" class, adding the ability to tween filters (like blurs, glows, drop shadows, bevels, etc.) as well as image effects like contrast, colorization, brightness, saturation, hue, and threshold (combined size: about 6k). The syntax is identical to the TweenLite class. If you're unfamiliar with TweenLite, I'd highly recommend that you check it out. It provides easy way to tween multiple object properties over time including a MovieClip's position, alpha, volume, color, etc. Just like the TweenLite class, TweenFilterLite allows you to build in a delay, call any function when the tween starts or has completed (even passing any number of parameters you define), automatically kill other tweens that are affecting the same object (to avoid conflicts), tween arrays, etc. One of the big benefits of this class (and the reason "Lite" is in the name) is that it was carefully built to minimize file size. There are several other Tweening engines out there, but in my experience, they required more than triple the file size which was unacceptable when dealing with strict file size requirements (like banner ads). I haven't been able to find a faster tween engine either. The syntax is simple and the class doesn't rely on complicated prototype alterations that can cause problems with certain compilers. TweenFilterLite is simple, very fast, and more lightweight (about 6k) than any other popular tweening engine.

And if you want even more features and don't mind a few extra Kb, check out the new TweenMax class which adds bezier tweening, pause/resume, easier sequencing, and more. It can do everything TweenFilterLite does plus more.

(Click here for the ActionScript 2.0 version of this class)

OBJECTIVES

  • Minimize file size
  • Maximize flexibility and efficiency by extending the TweenLite class. That way, if you don't need to tween filters, you can just use TweenLite (about 3k); otherwise, this class will only add another 3k (6k total)
  • Minimize the amount of code required to initiate a tween
  • Maximize performance
  • Allow for very flexible callbacks (onComplete, onUpdate, onStart, all with the ability to pass any number of parameters)

FILTERS & PROPERTIES:

  • blurFilter
    blurX, blurY, quality
  • glowFilter
    alpha, blurX, blurY, color, strength, quality
  • colorMatrixFilter
    colorize, amount, contrast, brightness, saturation, hue, threshold, relative, matrix
  • dropShadowFilter
    alpha, angle, blurX, blurY, color, distance, strength, quality
  • bevelFilter
    angle, blurX, blurY, distance, highlightAlpha, highlightColor, shadowAlpha, shadowColor, strength, quality

USAGE

TweenFilterLite.to(target:Object, duration:Number, variables:Object):TweenFilterLite

  • Description: Tweens the target's properties from whatever they are at the time you call the method to whatever you define in the variables parameter.
  • Parameters:
    1. target : Object - Target object whose properties we're tweening
    2. duration : Number - Duration (in seconds) of the tween
    3. variables : Object - An object containing the end values of all the properties you'd like to have tweened (or if you're using the TweenLite.from() method, these variables would define the BEGINNING values). Pass in one object for each filter (named appropriately, like blurFilter, glowFilter, colorMatrixFilter, etc.) Filter objects can contain any number of properties specific to that filter, like blurX, blurY, contrast, color, distance, colorize, brightness, highlightAlpha, etc.
      Special Properties:

      • delay : Number - Number of seconds to delay before the tween begins. This can be very useful when sequencing tweens.
      • ease : Function - You can specify a function to use for the easing with this variable. For example, fl.motion.easing.Elastic.easeOut. The Default is Regular.easeOut.
      • easeParams : Array - An array of extra parameter values to feed the easing equation. This can be useful when you use an equation like Elastic and want to control extra parameters like the amplitude and period. Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams.
      • autoAlpha : Number - Same as changing the "alpha" property but with the additional feature of toggling the "visible" property to false if the alpha ends at 0. It will also toggle visible to true before the tween starts if the value of autoAlpha is greater than zero.
      • volume : Number - To change a MovieClip's volume, just set this to the value you'd like the MovieClip to end up at (or begin at if you're using TweenFilterLite.from()).
      • tint : Number - To change a MovieClip's color, set this to the hex value of the color you'd like the MovieClip to end up at(or begin at if you're using TweenLite.from()). An example hex value would be 0xFF0000. If you'd like to remove the color from a MovieClip, just pass null as the value of tint. Before version 5.8, tint was called mcColor (which is now deprecated and will likely be removed at a later date although it still works)
      • frame : Number - Use this to tween a MovieClip to a particular frame.
      • onStart : Function - If you'd like to call a function as soon as the tween begins, pass in a reference to it here. This can be useful when there's a delay and you want something to happen just as the tween begins.
      • onStartParams : Array - An array of parameters to pass the onStart function.
      • onUpdate : Function - If you'd like to call a function every time the property values are updated (on every frame during the time the tween is active), pass a reference to it here.
      • onUpdateParams : Array - An array of parameters to pass the onUpdate function (this is optional)
      • onComplete : Function - If you'd like to call a function when the tween has finished, use this.
      • onCompleteParams : Array - An array of parameters to pass the onComplete function (this is optional)
      • renderOnStart : Boolean - If you're using TweenFilterLite.from() with a delay and want to prevent the tween from rendering until it actually begins, set this to true. By default, it's false which causes TweenFilterLite.from() to render its values immediately, even before the delay has expired.
      • overwrite : Boolean - If you do NOT want the tween to automatically overwrite any other tweens that are affecting the same target, make sure this value is false.
      • blurFilter : Object - To apply a BlurFilter, pass an object with one or more of the following properties:
        • blurX
        • blurY
        • quality
      • glowFilter : Object - To apply a GlowFilter, pass an object with one or more of the following properties:
        • alpha
        • blurX
        • blurY
        • color
        • strength
        • quality
        • inner
        • knockout
      • colorMatrixFilter : Object - To apply a ColorMatrixFilter, pass an object with one or more of the following properties:
        • colorize
        • amount
        • contrast
        • brightness
        • saturation
        • hue
        • threshold
        • relative
        • matrix
      • dropShadowFilter : Object - To apply a ColorMatrixFilter, pass an object with one or more of the following properties:
        • alpha
        • angle
        • blurX
        • blurY
        • color
        • distance
        • strength
        • quality
      • bevelFilter : Object - To apply a BevelFilter, pass an object with one or more of the following properties:
        • angle
        • blurX
        • blurY
        • distance
        • highlightAlpha
        • highlightColor
        • shadowAlpha
        • shadowColor
        • strength
        • quality



TweenFilterLite.from(target:Object, duration:Number, variables:Object):TweenFilterLite

  • Description: Exactly the same as TweenFilterLite.to(), but instead of tweening the properties from where they're at currently to whatever you define, this tweens them the opposite way - from where you define TO where ever they are now (when the method is called). This is handy for when things are set up on the stage the way the should end up and you just want to tween them to where they are.
  • Parameters: Same as TweenFilterLite.to(). (see above)



TweenLite.delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array):void

  • Description: Provides an easy way to call any function after a specified number of seconds. Any number of parameters can be passed to that function when it's called too.
  • Parameters:
    1. delay : Number - Number of seconds before the function should be called.
    2. onComplete : Function - The function to call
    3. onCompleteParams : Array - [optional] An array of parameters to pass the onComplete function when it's called.




TweenFilterLite.killTweensOf(target:Object, complete:Boolean);

  • Description: Provides an easy way to kill all tweens of a particular Object/MovieClip. You can optionally force it to immediately complete (which will also call the onComplete function if you defined one)
  • Parameters:
    1. target : Object Any/All tweens of this Object/MovieClip will be killed.
    2. complete : Boolean If true, the tweens for this object will immediately complete (go to the ending values and call the onComplete function if you defined one).




TweenFilterLite.killDelayedCallsTo(function:Function);

  • Description: Provides an easy way to kill all delayed calls to a particular function (ones that were instantiated using the TweenFilterLite.delayedCall() method).
  • Parameters:
    1. function : Function Any/All delayed calls to this function will be killed.


EXAMPLES

As a simple example, you could tween the blur of clip_mc from where it's at now to 20 over the course of 1.5 seconds by:

  1. import gs.TweenFilterLite;
  2. TweenFilterLite.to(clip_mc, 1.5, {blurFilter:{blurX:20, blurY:20}});


If you want to get more advanced and tween the clip_mc MovieClip over 5 seconds, changing the saturation to 0, delay starting the whole tween by 2 seconds, and then call a function named "onFinishTween" when it has completed and pass in a few arguments to that function (a value of 5 and a reference to the clip_mc), you'd do so like:

  1. import gs.TweenFilterLite;
  2. import fl.motion.easing.Back;
  3. TweenFilterLite.to(clip_mc, 5, {colorMatrixFilter:{saturation:0}, delay:2, onComplete:onFinishTween, onCompleteParams:[5, clip_mc]});
  4. function onFinishTween(argument1:Number, argument2:MovieClip):void {
  5.     trace("The tween has finished! argument1 = " + argument1 + ", and argument2 = " + argument2);
  6. }

If you have a MovieClip on the stage that already has the properties you'd like to end at, and you'd like to start with a colorized version (red: 0xFF0000) and tween to the current properties, you could:

  1. import gs.TweenFilterLite;
  2. TweenFilterLite.from(clip_mc, 5, {colorMatrixFilter:{colorize:0xFF0000}});

FAQ

  1. How do I install the class? Do I have to import it on every frame?
    Just make sure the "gs" folder from the download is in the same folder as your FLA file. Keep the class files in the "gs" folder (don't remove them). That's it. And, yes, just like any Class, you need to import TweenFilterLite at the top of any frame that contains code referencing it. This does NOT add extra Kb to your file size very time you import it. Flash is smart enough to embed it once and all the other import statments just act as a "pointer" to the embedded Class.

  2. Why doesn't the tweening engine selectively overwrite ONLY tweens that are affecting the same property? How can I achieve this effect?
    As you can tell from the speed tests, performance is a primary concern. Searching through potentially hundreds or thousands of tweens for overlapping tween properties can get expensive in terms of performance. Therefore, the TweenFilterLite family opted for a much faster approach: all or nothing. But don't worry - in almost every case, you can achieve the result you're after with a little bit of extra code. Trust me, it's worth the increased speed and efficiency you'll get.

    You can selectively kill tweens by keeping track of the TweenFilterLite instance that’s returned by the to() or from() methods, and calling removeTween() on them. For example, if you want to have a button scale up when you roll over it, and scale back down when you roll off (those tweens should overwrite each other) but you don't want them to overwrite a from() call that fades the button in over the course of 2 seconds, you could do:

    1. myButton.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
    2. myButton.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
    3. var scaleTween:TweenFilterLite;
    4. TweenFilterLite.from(myButton, 2, {alpha:0, overwrite:false});
    5. function onMouseOver($e:MouseEvent):void {
    6.     TweenFilterLite.removeTween(scaleTween);
    7.     scaleTween = TweenFilterLite.to(myButton, 0.5, {scaleX:1.2, scaleY:1.2, overwrite:false});
    8. }
    9. function onMouseOut($e:MouseEvent):void {
    10.     TweenFilterLite.removeTween(scaleTween);
    11.     scaleTween = TweenFilterLite.to(myButton, 0.5, {scaleX:1, scaleY:1, overwrite:false});
    12. }

    Remember, other tweens of the same object will always be overwritten by default. You must set overwrite:false to avoid that behavior. The above example is essentially allowing you to selectively handle overwriting yourself instead of relying on the tweening engine to do the "all or nothing" technique.

  3. Can I set up a sequence of tweens so that they occur one after the other?
    Of course! Just use the delay property and make sure you set the overwrite property to false (otherwise tweens of the same object will always overwrite each other to avoid conflicts). Here's an example where we colorize a MovieClip red over the course of 2 seconds, and then blur it over the course of 1 second:

    1. import gs.TweenFilterLite;
    2. TweenFilterLite.to(clip_mc, 2, {colorMatrixFilter:{colorize:0xFF0000, amount:1}});
    3. TweenFilterLite.to(clip_mc, 1, {blurFilter:{blurX:20, blurY:20}, delay:2, overwrite:false});

  4. Why aren't my filters working?
    If you're using a filter that has an alpha property, try setting it to 1. The default alpha value is zero, so the filter may be working just fine, but you're not seeing it.

  5. Do the properties have to be in a specific order?
    Nope. The only thing that matters is that the first parameter is the object you're tweening, the second parameter is the time (in seconds), and the third parameter contains all the properties you want to tween (in any order). So TweenFilterLite.to(clip_mc, 1, {colorMatrixFilter:{colorize:0xFF0000, amount:1}}) is the same as TweenFilterLite.to(clip_mc, 1, {colorMatrixFilter:{amount:1, colorize:0xFF0000}});

  6. Can I use TweenFilterLite to tween things other than filters?
    Sure. It extends TweenLite, so you can tween any property you want. TweenFilterLite.to(my_mc, 1, {x:200}) gives you the same result as TweenLite.to(my_mc, 1, {x:200}). However, I'd recommend using TweenLite to tween properties other than filters for two reasons:
    1. In order to accommodate the specialized nature of filters, TweenFilterLite's code is a bit lengthier which translates into more work for the processor. It's doubtful that anyone would notice a performance hit unless you're tweening hundreds or thousands of instances simultaneously, but I'm a bit of an efficiency freak.
    2. TweenLite can tween any property of ANY object whereas TweenFilterLite tweens properties of DisplayObjects (like MovieClips, Sprites, etc.)

  7. Why are TweenLite and TweenFilterLite split into 2 classes instead of building all the functionality into one class?
    1. File size. Only a portion of projects out there require tweening of filters. Almost every project I work on uses TweenLite, but only a few require tweening filters (TweenFilterLite). TweenLite is 3k whereas TweenFilterLite is 5k. Again, one of the stated purposes of TweenLite is to minimize file size & code bloat. If someone only wants to use TweenFilterLite, fine. But I think many people appreciate being able to use the most lightweight option for their needs and shave off the 3k when possible.
    2. Speed. Tweening filters is a more complex task. There are additional if/else statements and calculations in the rendering loop inside TweenFilterLite which could potentially slow things down a bit, even for non-filter tweens (I doubt anyone would notice a difference unless they’re running hundreds or thousands of simultaneous tweens, but I’m a big fan of keeping things as efficient & fast as possible)

  8. Do I have to purchase a license to use this code? Can I use it for commercial purposes?
    TweenFilterLite is free. You're welcome to use it for commercial purposes - I only ask that you donate what you think the class is worth in your project(s), and consider joining Club GreenSock which gives you some bonus classes, updates, and more. If you want to use one (or more) of my classes in your commerical software product which would entail distributing the class files, please get my permission first by e-mailing me at jack -at- greensock.com.

Need Help?

Feel free to e-mail me a question. I'd highly recommend joining Club GreenSock to get prioritized access to my time in answering your question, and so that you receive updates and lots more. When you e-mail your question, please include a simplified FLA file (and any class files) that clearly demonstrates the problem and provide a brief explanation.

Author: Jack Doyle, (e-mail: jack -at- greensock.com)
Copyright 2008, GreenSock (This work is subject to the terms here.)

25 Responses to 'TweenFilterLite (AS3 Version) - Easily Tween Filters & Image Effects'

Subscribe to comments with RSS

  1. Robert said,

    on May 30th, 2007 at 8:29 pm

    Jack

    many thanks for sharing your hard work. Having found the MC Tween class to be hugely timesaving and extremely useful I was looking for somthing that could product similar effects on color and brightness properties.

    I’m sure it will become a key tool in future development

    Regards

    Robert

  2. Bryan Bartow said,

    on June 2nd, 2007 at 3:14 am

    Jack, thanks for creating this handy class. I can already tell that it will save me a fair amount of time. I’ll be sure to let you know if I publish anything that uses the class.

  3. Zsotl Popa said,

    on June 14th, 2007 at 2:08 am

    Hello Jack, i just want to say a “thank you” here too, because i’m really amazed about your work and your helpfull mentality, love your tween, its a big help to me.

    regards
    Zsolt

  4. Nate said,

    on July 31st, 2007 at 10:04 am

    Much thanks for this great little package. I’ve been looking for a solid animation package to accompany AS3 projects and I think I’ve finally found it. Kudos on your work!

  5. Stephen Koch said,

    on August 3rd, 2007 at 11:53 am

    Nice work. Thanks.

  6. ghis_le_fou said,

    on August 21st, 2007 at 2:02 pm

    Thanksa lot for your class … but i have a problem …

    is it possible to initialize a movieclip with a tween effect in 0 second like this :

    TweenFilterLite.to(mc, 0, {colorMatrixFilter:{contrast:3, brightness:3}});

    According to me, it doesn’t work …. :-(

    is there a trick ?

    Thanks a lot again …

    Very nice work !!!

  7. jack said,

    on August 21st, 2007 at 2:58 pm

    Good news ghis_le_fou - I JUST updated the class to allow for durations of 0! Version 4.5 and later should work great for you.

  8. Sean said,

    on August 30th, 2007 at 10:12 am

    For those of you who want to use this class in Flex … ITS EASY.
    Flex does not allow you to add to the Application stage a MovieClip and this class uses a MovieClip for all of its methods ….

    Solution:

    Simply subclass any class you want ( for example ) and than continue by implementing two public methods in this class as follows:

    public function set quality(i:int):void {}

    public function get quality():int {
    return 1;
    }

    That’s it …

    Now use your class instead of MC.

    Enjoy.

    Sean - HeliHobby.com

  9. Sean said,

    on September 13th, 2007 at 1:22 pm

    Hi Jack,
    How can I kill the running tweens in TweenFilterLite .

    The TweenFilterLite.killTweensOf(target:Object) does not seem to be implemented in the SubClasses TweenFilterLite.

    Regards,

    Sean.

  10. jack said,

    on September 14th, 2007 at 9:59 am

    Sean, great catch. Looks like Adobe changed the way inheritance is handled in AS3 which made the killTweensOf() and delayedCall() and killDelayedCallsTo() unavailable when called as static methods of TweenFilterLite. As of version 4.8, that’s fixed.

  11. blogk said,

    on November 26th, 2007 at 9:45 am

    great class and all, it’s the best in terms of filesize and simplicity, BUT:

    sometimes (and it really is _essentially_ random) it throws an error

    TypeError: Error #1010: A term is undefined and has no properties.
    at gs::TweenFilterLite/render()
    at gs::TweenLite$/executeAll()

    when trying to tween blur filter. it stops execution of the tween and usually occurs when tweening blur filter of more than 40 instances at once.

    and this has been a real pain in the ass!!

  12. jack said,

    on November 26th, 2007 at 4:09 pm

    blogk, after many hours of banging my head against the screen and trying to chase down the rare (and apparently completely random) 1010 error that TweenFilterLite throws from time to time in specific scenarios, I think I’ve figured it out. Actually, I’m almost positive it was caused by a bug in Flash but I whipped together a workaround and implemented it in version 5.5 of the class.

    Thanks for the feedback.

  13. Felixz said,

    on December 23rd, 2007 at 1:24 pm

    I have a problem using TweenFilterLite with textFields…
    TweenFilterLite.to(someTextField,2,{type:”glow”,color:0×0000FF,blurX:20,blurY:10,strength:100});
    I constantly get:
    ArgumentError: Error #2008: Parameter type must be one of the accepted values.
    at flash.text::TextField/set type()
    at gs::TweenFilterLite/render()
    at gs::TweenLite$/executeAll()

  14. jack said,

    on December 26th, 2007 at 1:48 pm

    Felixz, great catch. As of version 5.84, the error is fixed and you can now tween filters on TextFields.

  15. Tony said,

    on March 7th, 2008 at 7:39 pm

    Another quickie, Jack:
    Could you post a quick tut on sound tweening of loaded mp3s (with other tweens running as well)? I’ve messed around with both the loaded sound as well as a SoundChannel, but a desired volume tween doesn’t seem to work. Or is this only possible with the newest version?

    Thanks again.

    – Tony

  16. jack said,

    on March 7th, 2008 at 11:11 pm

    Tony, tweening audio volume can be done two ways:

    1) On a MovieClip that contains audio. This is as simple as:
    TweenLite.to(myMovieClip, 2, {volume:0});

    2) On a SoundChannel object.This is likely what you’d do with the MP3s you loaded in. When you play() your audio, it returns a SoundChannel object, so once you’ve loaded your MP3, it should be as easy as:

    var myChannel = mySound.play();
    TweenLite.to(myChannel, 2, {volume:0});

    Keep in mind, you’re NOT tweening the Sound object - you’re tweening the SoundChannel object.

  17. John said,

    on March 10th, 2008 at 11:32 pm

    How can I set it to loop and change colors ramdonly or using an aray of colors?

    Awesome work.

  18. jack said,

    on March 11th, 2008 at 10:05 am

    John, you could accomplish what you’re after with something like:

    var myColors:Array = [0xFF0000, 0×00FF00, 0×0000FF];
    function tweenColor():void {
    var randomColor = myColors[Math.floor(Math.random() * myColors.length)];
    TweenFilterLite.to(my_mc, 2, {colorMatrixFilter:{colorize:randomColor, amount:2}, onComplete:tweenColor});
    }
    tweenColor();

  19. Biffer said,

    on March 11th, 2008 at 11:07 am

    Hi there i have added an additional class for those who wish to use Events. This is a seperate class - so just use this instead of TweenLite.

    A data object is dispatched with the Event so you can still pass around onStartParams etc in the usual way but just pick them up from the event listener.

    hope this is some good to you event loving types.

    http://biffcom.com/resource/tweenLiteEventMod/TweenLiteEventModExample.zip

    Thanks,

    Biffer Rowley

  20. Tony said,

    on March 13th, 2008 at 2:32 am

    John:
    Or you could just randomize the “hue” color parameter which is handily a 0-360 scale in TweenFilterLite:

    theHue = (Math.round(Math.random() * 360)) ;
    TweenFilterLite.to(my_mc, 2, {colorMatrixFilter:{amount:1, hue:theHue}});

    You can enhance the effect with the brightness parameter as well (-1 to 1 scale). Very cool result with sky images.
    –Tony

  21. Nicolas said,

    on April 3rd, 2008 at 5:11 am

    How i can dublicate effect like flash bulb. It is simple in Tweener.
    Tweener.addTween(_loader,{_color_rb:255, _color_gb:255, _color_bb:255, time:1, transition:”easeOutQuad”});

    I try use brightness with param 3 but result is poor for me.

  22. jack said,

    on April 3rd, 2008 at 11:36 pm

    Nicolas, you can definitely create the effect you’re looking for using the ColorTransformProxy utility class I created for use in conjunction with TweenLite for tweening all the various ColorTransform-related properties, including redOffset, greenOffset, blueOffset, redMultiplier, greenMultiplier, blueMultiplier, tint, and even tintPercent and brightness!. Sign up for Club GreenSock and you’ll get that class as a bonus (as well as a TrasnformMatrixProxy class). See http://blog.greensock.com/club/ for details.

  23. Lauren said,

    on April 20th, 2008 at 3:31 pm

    Thanks for providing this! Fantastic tool.

  24. Erich said,

    on May 8th, 2008 at 12:46 pm

    Jack, thanks for creating these great classes. You’ve saved me hours of time. If you’re ever in Chicago, I owe you a beer.

  25. brroy said,

    on May 12th, 2008 at 10:25 am

    I’ve been looking for a solid animation package to accompany AS3 projects and I think I’ve finally found it. Kudos on your work!

    helipross.com

Leave a Reply