package { import aether.effects.carnival.KaleidoscopeEffect; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.net.FileFilter; import flash.net.FileReference; [SWF(width=500, height=500, backgroundColor=0xCCCCCC)] /** * Shows how kaleidoscope effect can be achieved with aether effect. This also * animates the effect so that the kaleidoscope spins automatically. */ public class graphic_flex_image_effects_12_Flex_AetherKaleidoscope extends Sprite { // number of segments in kaleidoscope private static const NUM_SEGMENTS:uint = 8; private var _file:FileReference; private var _originalImage:BitmapData; private var _kaleidoscope:Bitmap; private var _angle:Number; /** * Constructor. This sets up a listener for when the stage is clicked. */ public function graphic_flex_image_effects_12_Flex_AetherKaleidoscope() { stage.addEventListener(MouseEvent.CLICK, onStageClick); } /** * Applies the kaleidoscope effect to clone of original loaded image. */ private function applyEffect():void { // clone original so that it remains undistorted var clone:BitmapData = _originalImage.clone(); // apply effect with current angle value to clone new KaleidoscopeEffect(NUM_SEGMENTS, _angle).apply(clone); _kaleidoscope.bitmapData.dispose(); _kaleidoscope.bitmapData = clone; } /** * Handler for when stage is clicked. This opens file browse dialog. * * @param event Event dispatched by stage. */ private function onStageClick(event:MouseEvent):void { _file = new FileReference(); _file.addEventListener(Event.SELECT, onFileSelect); _file.browse([new FileFilter("Images", "*.jpg;*.jpeg;*.gif;*.png")]); } /** * Handler for when a file is selected. Loads file. * * @param event Event dispatched by FileReference. */ private function onFileSelect(event:Event):void { stage.removeEventListener(MouseEvent.CLICK, onStageClick); _file.addEventListener(Event.COMPLETE, onImageLoadComplete); _file.load(); } /** * Handler for when local image completes loading. This loads bytes into Loader for access. * * @param event Event dispatched by FileReference. */ private function onImageLoadComplete(event:Event):void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLocalFileRead); loader.loadBytes(_file.data); } /** * Handler for when bytes from local file are read into Loader. This kicks off the effect with * the loaded image and sets up an ENTER_FRAME listener so that the effect may be animated. * * @param event Event dispatched by LoaderInfo. */ private function onLocalFileRead(event:Event):void { var loaderInfo:LoaderInfo = event.target as LoaderInfo; // add initial image to stage _kaleidoscope = loaderInfo.content as Bitmap; addChild(_kaleidoscope); var width:Number = stage.stageWidth; var height:Number = stage.stageHeight; // will be used to save reference to original image, scaled to stage _originalImage = new BitmapData(width, height); var bitmapData:BitmapData = _kaleidoscope.bitmapData; var matrix:Matrix = new Matrix(); // scale loaded image to stage size matrix.scale(width/bitmapData.width, height/bitmapData.height); _originalImage.draw(bitmapData, matrix); _angle = 0; // apply initial effect applyEffect(); addEventListener(Event.ENTER_FRAME, onSpriteEnterFrame); } /** * Handler for ENTER_FRAME. This updates current angle of effect and reapplies effect. * * @param event Event dispatched by this sprite. */ private function onSpriteEnterFrame(event:Event):void { _angle += 1; applyEffect(); } } }