AS3: DistortionTweener
View Example 1
View Example 2
View Example 3
View Documentation
Download Class & Example Files
The DistortionTweener allows you to distort four points of an object. It is an easy to way make distortions such as trapezoids on a movie clip.
The DistortionTweener uses Ruben Swieringa's DistortImage class and is based on a sample .FLA provided by Tam Ho on how to use DistortImage in Flash.
Actionscript:
-
/**
-
* The DistortionTweener allows you to distort four points of an object. It is an easy to way make distortions such as trapezoids on a movie clip.
-
*
-
* The DistortionTweener uses Ruben Swieringa's DistortImage class (http://www.rubenswieringa.com/blog/distortimage) and is based on a sample .FLA provided by Tam Ho (http://www.flashteam.com.au) on how to use DistortImage in Flash.
-
*
-
* @usage
-
* <code>
-
* <pre>
-
import com.reintroducing.transitions.DistortionTweener;
-
import fl.transitions.easing.Regular;
-
var dt:DistortionTweener = new DistortionTweener(s, clip_mc, tl, tr, br, bl, 5);
-
dt.addEventListener(Event.INIT, onDistortStarted);
-
dt.addEventListener(Event.COMPLETE, onDistortFinished);
-
dt.tweenTo(new Point(-50, -50), new Point(410, -50), new Point(310, 266), new Point(50, 266), Regular.easeIn, .5);
-
// fired off when the distortion tween starts
-
function onDistortStarted($evt:Event):void
-
{
-
trace("Starting the distortion.");
-
}
-
// fired off whent he distortion tween ends
-
function onDistortFinished($evt:Event):void
-
{
-
trace("Finished the distortion.");
-
}
-
* </pre>
-
* </code>
-
*
-
* @author Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.0
-
*/
-
-
package com.reintroducing.transitions
-
{
-
import flash.display.Bitmap;
-
import flash.display.BitmapData;
-
import flash.display.MovieClip;
-
import flash.display.Shape;
-
import flash.events.Event;
-
import flash.events.EventDispatcher;
-
import flash.geom.Point;
-
-
import org.flashsandy.display.DistortImage;
-
-
import fl.transitions.Tween;
-
import fl.transitions.TweenEvent;
-
-
public class DistortionTweener extends EventDispatcher
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
private var _holder:*;
-
private var _mc:MovieClip;
-
private var _mcWidth:Number;
-
private var _mcHeight:Number;
-
private var _bmd:BitmapData;
-
private var _bmp:Bitmap;
-
private var _container:Shape;
-
private var _tl:Point;
-
private var _tr:Point;
-
private var _br:Point;
-
private var _bl:Point;
-
private var _distortion:DistortImage;
-
private var _tweenFunc:Function;
-
private var _tweenTime:Number;
-
private var _precision:uint;
-
-
// tweens
-
private var _tlXTween:Tween;
-
private var _tlYTween:Tween;
-
private var _trXTween:Tween;
-
private var _trYTween:Tween;
-
private var _brXTween:Tween;
-
private var _brYTween:Tween;
-
private var _blXTween:Tween;
-
private var _blYTween:Tween;
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
public static const DEFAULT_NAME:String = "com.reintroducing.transitions.DistortionTweener";
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
/**
-
* Creates a new instance of the DistortionTweener class. The point values are relative to the holder clip, NOT the stage.
-
*
-
* @usage <pre><code>var dt:DistortionTweener = new DistortionTweener($holder, $mc, $tl, $tr, $br, $bl, $precision);</code></pre>
-
*
-
* @param $holder The DisplayObject that will be used to hold your distorted bitmap
-
* @param $mc The source movie clip that will be used to copy into the bitmap that will be distorted
-
* @param $tl The top left point to use in the distortion
-
* @param $tr The top right point to use in the distortion
-
* @param $br The bottom right point to use in the distortion
-
* @param $bl The bottom left point to use in the distortion
-
* @param $precision A uint representing the value to use as the precision in the DistortImage class
-
*/
-
-
public function DistortionTweener($holder:*, $mc:MovieClip, $tl:Point, $tr:Point, $br:Point, $bl:Point, $precision:uint):void
-
{
-
this._holder = $holder;
-
this._mc = $mc;
-
this._mcWidth = this._mc.width;
-
this._mcHeight = this._mc.height;
-
this._tl = $tl;
-
this._tr = $tr;
-
this._br = $br;
-
this._bl = $bl;
-
this._precision = $precision;
-
-
this.init();
-
}
-
-
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
-
-
private function init():void
-
{
-
this._mc.visible = false;
-
-
this._bmd = new BitmapData(this._mcWidth, this._mcHeight, true, 0x00FFFFFF);
-
this._bmd.draw(this._mc);
-
-
this._bmp = new Bitmap(this._bmd);
-
this._container = new Shape();
-
-
this._holder.addChild(this._container);
-
-
this._distortion = new DistortImage(this._mcWidth, this._mcHeight, this._precision, this._precision);
-
this._distortion.setTransform(this._container.graphics, this._bmp.bitmapData, this._tl, this._tr, this._br, this._bl);
-
}
-
-
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
-
-
/**
-
* Tweens the distortion. As with the constructor, the point values are relative to the holder clip, NOT the stage.
-
*
-
* <p>
-
* The tweenTo method dispatches two events:
-
* <ul>
-
* <li>Event.INIT: Dispatched when the tweening begins</li>
-
* <li>Event.COMPLETE: Dispatched when the tweening ends</li>
-
* </ul>
-
* </p>
-
*
-
* @usage <pre><code>dt.tweenTo(new Point(-50, -50), new Point(410, -50), new Point(310, 266), new Point(50, 266), Regular.easeIn, .5);</code></pre>
-
*
-
* @param $tl The top left point to end the tween at
-
* @param $tr The top right point to end the tween at
-
* @param $br The bottom right point to end the tween at
-
* @param $bl The bottom left point to end the tween at
-
* @param $tweenFunc The easing function to use in the tween
-
* @param $time The duration, in seconds, of the tween
-
*
-
* @return Nothing
-
*/
-
-
public function tweenTo($tl:Point, $tr:Point, $br:Point, $bl:Point, $tweenFunc:Function, $time:Number):void
-
{
-
this.dispatchEvent(new Event(Event.INIT));
-
-
this._tweenFunc = $tweenFunc;
-
this._tweenTime = $time;
-
-
// top left tweens
-
this._tlXTween = new Tween(this._tl, "x", this._tweenFunc, this._tl.x, $tl.x, this._tweenTime, true);
-
this._tlYTween = new Tween(this._tl, "y", this._tweenFunc, this._tl.y, $tl.y, this._tweenTime, true);
-
-
// top right tweens
-
this._trXTween = new Tween(this._tr, "x", this._tweenFunc, this._tr.x, $tr.x, this._tweenTime, true);
-
this._trYTween = new Tween(this._tr, "y", this._tweenFunc, this._tr.y, $tr.y, this._tweenTime, true);
-
-
// bottom right tweens
-
this._brXTween = new Tween(this._br, "x", this._tweenFunc, this._br.x, $br.x, this._tweenTime, true);
-
this._brYTween = new Tween(this._br, "y", this._tweenFunc, this._br.y, $br.y, this._tweenTime, true);
-
-
// bottom left tweens
-
this._blXTween = new Tween(this._bl, "x", this._tweenFunc, this._bl.x, $bl.x, this._tweenTime, true);
-
this._blYTween = new Tween(this._bl, "y", this._tweenFunc, this._bl.y, $bl.y, this._tweenTime, true);
-
-
this._blYTween.addEventListener(TweenEvent.MOTION_CHANGE, render);
-
this._blYTween.addEventListener(TweenEvent.MOTION_FINISH, onFinished);
-
}
-
-
/**
-
* Resets the bitmap to the specified points.
-
*
-
* @usage <pre><code>dt.reset(new Point(0, 0), new Point(clip_mc.width, 0), new Point(clip_mc.width, clip_mc.height), new Point(0, clip_mc.height));</code></pre>
-
*
-
* @param $tl The top left point to use in the distortion
-
* @param $tr The top right point to use in the distortion
-
* @param $br The bottom right point to use in the distortion
-
* @param $bl The bottom left point to use in the distortion
-
*
-
* @return Nothing
-
*/
-
-
public function reset($tl:Point, $tr:Point, $br:Point, $bl:Point):void
-
{
-
this._tl = $tl;
-
this._tr = $tr;
-
this._br = $br;
-
this._bl = $bl;
-
-
this._container.graphics.clear();
-
this._holder.removeChild(this._container);
-
-
this._container = null;
-
this._container = new Shape();
-
-
this._holder.addChild(this._container);
-
}
-
-
/**
-
* Cleans up the DistortionTweener for garbage collection.
-
*
-
* @usage <pre><code>dt.destroy();</code></pre>
-
*
-
* @return Nothing
-
*/
-
-
public function destroy():void
-
{
-
this._bmd.dispose();
-
-
this._container.graphics.clear();
-
this._holder.removeChild(this._container);
-
-
this._bmd = null;
-
this._bmp = null;
-
this._container = null;
-
this._holder = null;
-
this._distortion = null;
-
}
-
-
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
-
-
// Dispatched during the MOTION_CHANGE event to update the distorted graphics.
-
private function render($evt:TweenEvent):void
-
{
-
this._container.graphics.clear();
-
this._distortion.setTransform(this._container.graphics, this._bmp.bitmapData, this._tl, this._tr, this._br, this._bl);
-
}
-
-
// Dispatches a COMPLETE event when the distortion is finished.
-
private function onFinished($evt:TweenEvent):void
-
{
-
this._blYTween.removeEventListener(TweenEvent.MOTION_CHANGE, render);
-
this._blYTween.removeEventListener(TweenEvent.MOTION_FINISH, onFinished);
-
-
this._tlXTween = null;
-
this._tlYTween = null;
-
this._trXTween = null;
-
this._trYTween = null;
-
this._brXTween = null;
-
this._brYTween = null;
-
this._blXTween = null;
-
this._blYTween = null;
-
-
this.dispatchEvent(new Event(Event.COMPLETE));
-
}
-
-
//- GETTERS & SETTERS -------------------------------------------------------------------------------------
-
-
-
-
//- HELPERS -----------------------------------------------------------------------------------------------
-
-
public override function toString():String
-
{
-
return "com.reintroducing.transitions.DistortionTweener";
-
}
-
-
//- END CLASS ---------------------------------------------------------------------------------------------
-
}
-
}

(8 votes, average: 4.38 out of 5)









[...] here for [...]
Nice one Matt! Do note that I can't really take credit for the distortion-technique myself, DistortImage was originally written by Thomas Pfeiffer, I merely ported it to an Actionscript3.0 class.
That is absolutely correct. I forgot to mention that in my posts but if anyone reads the DistortImage credits, hopefully they will see that. Thanks Ruben.
Hi Matt,
SWEET! Can you please release an AS2 version of this, pretty please!?
please, please, please..... its all I really want for the holidays.... please!
no love for an AS2 version .....
Sorry WT, there wasn't any plans for an AS2 version of this really. You could probably convert it easily but you'd have to get Thomas Pfeiffer's AS2 DistortImage class as Ruben mentioned he used on his AS3 conversion and the rest should just be AS3 to AS2 code conversion. If I have some free time I may try to get it up but I've got a lot of other things in the works for the site that I'd rather get done first so when I do finally get free time I'm going to be working on those before I would an AS2 version of this.
[...] Download full source code and check examples. No Comments Leave a Commenttrackback addressThere was an error with your comment, please try again. name (required)email (will not be published) (required)url [...]
Hi!
I loved your class, but I have a problem with it.
I want to keep my MC after distorting it. It is important to me because in my project I'm distorting 5 clips, and I wrote a lot of code involving them. But when I'm finished with distorting, I guess my clip becomes trapped in container sprite. So I loose it when I call destroy method. Also I can't do anything with my MC's (like tween them) because they are in container.
Can you help me with that?
I would be very gratefull.
Best regards,
Vjekoslav Ratkajec
Hey Vjekoslav,
The DistortionTweener doesn't affect your clip, it makes a duplicate of your clip in the form of a BitmapData and it puts that in the container and runs the distortion on that. If you're using the code from my example, i specifically in there put code to hide the original movie clip and then show it after the transformation is complete, so all you would have to do in your code is to follow that same model.
now, if you're talking about distorting your clip and then trying to do things to the distorted clip, that won't work, because that can't take events or anything like that. the distortion tweener is only for tweening distortions to and from movie clips, you can't tween it into a distorted state and then do anything on it because your actual clip isnt the one being distorted. make sense?
Hi Matt,
thanks for the fast reply!
Well I found what was bothering me and why didn't clip appear after destorying it.
It's working fine now, but just to let you know, I added:
this._mc.visible = true;
in destroy method.
So mine working version of your class is:
public function destroy():void
{
this._bmd.dispose();
this._mc.visible = true;
this._container.graphics.clear();
this._holder.removeChild(this._container);
this._bmd = null;
this._bmp = null;
this._container = null;
this._holder = null;
this._distortion = null;
}
Thank you again, you helped me alot!
Best regards,
Vjekoslav Ratkajec
no problem, glad it helped!
Hi Matt,
Can distortionTweener be used to recreate the Mac style squeeze transition as displayed here:
http://www.scottgmorgan.com/blog/index.php/2007/11/15/grant-skinners-osx-squeeze-effect-in-as3/
http://www.gskinner.com/blog/archives/2007/11/squeeze_effect.html
If so how? I've been trying at it but can't get it. Seems like easing for the top and bottom parts of the the slide are different in the osx style transition. And I don't think two distortionTweens can be applied to the same mc at the same time.
Is this effect possible with DistortionTweener or DistortImage classes?
Hey Evan,
Unfortunately you can't achieve that effect with it. You can get something similar (because the distortion is only applied to four points) but not that exact thing. You can use it to distort it into a trapezoidal shape and then tween the two top points out to form a rectangle, but thats about it.
Thanks for your prompt reply Matt and your generous contribution of Distortion Tweener to actionscripters. Your answer was a surprise to me as I had expected you to say that Mac style effect was doable but I definitely take your word for it.
I was hoping to have a Mac OS style "swoosh" transition effect for a little app I'm working on using the Distort Image or DistortionTweener but I now know better. I had thought that maybe DistortImage could do the trick with different easing and/or tweening values for top-r/l and bottomr/l at different rates but I have been saved a lot of frustration and time by knowing now that it is not doable.
The other displacement map way of doing it I found was too processor intensive on slower computers (even in AS3).
In your estimation, would the something similar way of doing it with Distortion Tweener be as spectacular? What kind of even more spectacular slide transitions could be developed with Distortion Tweener then?
Evan,
I think something to look into which would maybe give you a similar effect (or something close) would be perlin noise and applying it to the movie clip you want to distort. Unfortunately I don't know off the top of my head how exactly youd go about it but if you play with it you may be able to get something close.
Have you downloaded and looked at Grant Skinner's file? I didn't but I'd imagine you could probably repurpose that somehow. Grant is a great coder so I'm sure you could go off of his files or maybe even ask him for some help.
Hi.
i`m kinda new to this, But is it possible to add a delay beefore the animation starts..?
-Kristian
Kristian,
Sure, before calling the tweenTo method just set your delay or call tweenTo anywhere you want it to happen in your code.
hi there,
great class. i just been think that you could replace the type of both the holder and the mc by DisplayObject. there is no need for a MovieClip, and the holder has to be a DisplayObject. anyways thanks for your effort, i will definitely use this class in upcoming projects.
cheers, jan
ooops. i'm sorry the holder of cource need to be at least a DisplayObjectContainer for the addchild method. stupid me.