In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Ripples

An implementation using a Ripple class I found.
package {
    import flash.geom.Rectangle;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.display.BitmapData;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    public class Ripple extends Sprite {
        private var W:int = 465;
        private var H:int = 465; 
        
        private var myRippler:Rippler;
        var rippleTarget:Bitmap;
        
        public function Ripple() {
            var rippleBitmap:BitmapData=new BitmapData(W,H,false,0);
            var ripplePicture:BitmapData = drawBg();
            var timer:Timer=new Timer(300);
            timer.start();
            rippleBitmap.draw(ripplePicture);
            rippleTarget=new Bitmap(rippleBitmap);
            addChild(rippleTarget);
            
            var overlay:BitmapData = new BitmapData(W, H, true, 0xFF000000)
            addChild(new Bitmap(overlay));
            
            myRippler=new Rippler(rippleTarget,overlay,20,5,5);
            stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMoveTriggered);
            timer.addEventListener(TimerEvent.TIMER, onTimerTriggered);
        }
        
        private function onMouseMoveTriggered(e:MouseEvent):void {
            myRippler.drawRipple(rippleTarget.mouseX,rippleTarget.mouseY,20,1);
        }
        
        private function onTimerTriggered(e:TimerEvent):void {
            var posX:Number=Math.random()*640;
            var posY:Number=Math.random()*480;
            myRippler.drawRipple(posX,posY,15,5);
        }
        
        private function drawBg():BitmapData {
            var bmd:BitmapData = new BitmapData(W, H, true, 0xFF000000)
            
            var x:int, y:int;
            var size:int = 15;
            var myRect:Rectangle = new Rectangle(0,0,size,size);
            
            for(x = 0; x<W; x+=size) {
                for(y = 0; y<H; y+=size) {
                    myRect.x = x; myRect.y = y;
                    bmd.fillRect(myRect, ((x+y)&1) == 0 ? 0xFF000044 : 0xFF004400 );
                }
            }
            
            return bmd;
        }
    }

}
import flash.display.Bitmap;
        
        






    import flash.display.BitmapData;

    import flash.display.BitmapDataChannel
    import flash.display.BlendMode;
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.filters.ConvolutionFilter;
    import flash.filters.DisplacementMapFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    class Rippler
    {
        // The DisplayObject which the ripples will affect.
        private var _source : DisplayObject;
        
        // Two buffers on which the ripple displacement image will be created, and swapped.
        // Depending on the scale parameter, this will be smaller than the source
        private var _buffer1 : BitmapData;
        private var _buffer2 : BitmapData;
        
        // The final bitmapdata containing the upscaled ripple image, to match the source DisplayObject
        private var _defData : BitmapData;
        
        // Rectangle and Point objects created once and reused for performance
        private var _fullRect : Rectangle;            // A buffer-sized Rectangle used to apply filters to the buffer
        private var _drawRect : Rectangle;            // A Rectangle used when drawing a ripple
        private var _origin : Point = new Point();    // A Point object to (0, 0) used for the DisplacementMapFilter as well as for filters on the buffer
        
        // The DisplacementMapFilter applied to the source DisplayObject
        private var _filter : DisplacementMapFilter;
        // A filter causing the ripples to grow
        private var _expandFilter : ConvolutionFilter;
        
        // Creates a colour offset to 0x7f7f7f so there is no image offset due to the DisplacementMapFilter
        private var _colourTransform : ColorTransform;
        
        // Used to scale up the buffer to the final source DisplayObject's scale
        private var _matrix : Matrix;
        
        // We only need 1/scale, so we keep it here
        private var _scaleXInv : Number;
        private var _scaleYInv : Number;
        
        /**
         * Creates a Rippler instance.
         * 
         * @param source The DisplayObject which the ripples will affect.
         * @param strength The strength of the ripple displacements.
         * @param scale The size of the ripples. In reality, the scale defines the size of the ripple displacement map (map.width = source.width/scale). Higher values are therefor also potentially faster.
         *  
         */
         
        private var _overlay:BitmapData;
         
        public function Rippler(source : DisplayObject, overlay:BitmapData, strength : Number, scaleX : Number = 2, scaleY : Number = 2)
        {
            _overlay = overlay;
            
            var correctedScaleX : Number;
            var correctedScaleY : Number;
            
            _source = source;
            _scaleXInv = 1/scaleX;
            _scaleYInv = 1/scaleY;
            
            // create the (downscaled) buffers and final (upscaled) image data, sizes depend on scale
            _buffer1 = new BitmapData(source.width*_scaleXInv, source.height*_scaleYInv, false, 0x00000000);
            _buffer2 = new BitmapData(_buffer1.width, _buffer1.height, false, 0x00000000);
            _defData = new BitmapData(source.width, source.height, false, 0x000000);
            
            // Recalculate scale between the buffers and the final upscaled image to prevent roundoff errors.
            correctedScaleX = _defData.width/_buffer1.width;
            correctedScaleY = _defData.height/_buffer1.height;
            
            // Create reusable objects
            _fullRect = new Rectangle(0, 0, _buffer1.width, _buffer1.height);
            _drawRect = new Rectangle();
            
            // Create the DisplacementMapFilter and assign it to the source
            _filter = new DisplacementMapFilter(_defData, _origin, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE, strength, strength, "wrap");
            _source.filters = [_filter];
            
            // Create a frame-based loop to update the ripples
            _source.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
            
            // Create the filter that causes the ripples to grow.
            // Depending on the colour of its neighbours, the pixel will be turned white
            _expandFilter = new ConvolutionFilter(3, 3, [0.5, 1, 0.5, 1, 0, 1, 0.5, 1, 0.5], 3);
            
            // Create the colour transformation based on 
            _colourTransform = new ColorTransform(1, 1, 1, 1, 128, 128, 128);
            
            // Create the Matrix object
            _matrix = new Matrix(correctedScaleX, 0, 0, correctedScaleY);
            
        }
        
        /**
         * Initiates a ripple at a position of the source DisplayObject.
         * 
         * @param x The horizontal coordinate of the ripple origin.
         * @param y The vertical coordinate of the ripple origin.
         * @param size The size of the ripple diameter on first impact.
         * @param alpha The alpha value of the ripple on first impact.
         */
        public function drawRipple(x : int, y : int, size : int, alpha : Number) : void
        {
            var half : int = size >> 1;        // We need half the size of the ripple
            var intensity : int = (alpha*0xffffff & 0xffffff)*alpha;    // The colour which will be drawn in the currently active buffer
            
            // calculate and draw the rectangle, having (x, y) in its centre
            _drawRect.x = (-half+x)*_scaleXInv;    
            _drawRect.y = (-half+y)*_scaleYInv;
            _drawRect.width = size*_scaleXInv;
            _drawRect.height = size*_scaleYInv;
            _buffer1.fillRect(_drawRect, intensity);
        }
        
           /**
            * Returns the actual ripple image.
            */
        public function getRippleImage() : BitmapData
        {
            return _defData;
        }
        
        /**
         * Removes all memory occupied by this instance. This method must be called before discarding an instance.
         */
        public function destroy() : void
        {
            _source.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
            _buffer1.dispose();
            _buffer2.dispose();
            _defData.dispose();
        }
        
        // the actual loop where the ripples are animated
        private function handleEnterFrame(event : Event) : void
        {
            // a temporary clone of buffer 2
            var temp : BitmapData = _buffer2.clone();
            // buffer2 will contain an expanded version of buffer1
            _buffer2.applyFilter(_buffer1, _fullRect, _origin, _expandFilter);
            // by substracting buffer2's old image, buffer2 will now be a ring
            _buffer2.draw(temp, null, null, BlendMode.SUBTRACT, null, false);
            // scale up and draw to the final displacement map, and apply it to the filter
            _defData.draw(_buffer2, _matrix, _colourTransform, null, null, true);
            _filter.mapBitmap = _defData;
            _source.filters = [_filter];         
            
            ///////////////////////////////////////////
            // UNCOMMENT THIS TO SHOW THE RAW SOURCE //
            ///////////////////////////////////////////
            _overlay.fillRect(_overlay.rect, 0x00000000);
            _overlay.draw(_defData, null, new ColorTransform(1,1,1,0.2));
            
            temp.dispose();
            // switch buffers 1 and 2
            switchBuffers();
        }
        
        // switch buffer 1 and 2, so that 
        private function switchBuffers() : void
        {
            var temp : BitmapData;
            temp = _buffer1;
            _buffer1 = _buffer2;
            _buffer2 = temp;
        }
        
    }