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

Realistic/Dynamic Fluid Ripple Component

/**
 * Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ufHA
 */

// forked from matacat's RIPPLE
//========================================================
// Ripple effect with DisplacementMapFilter
// Click the stage!
//
// 波紋の拡大・透明化も重いけど、それ以上にフィルタの再設定が重い。
// なんでフィルタって直にいじれないんだろう…
//========================================================

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.DisplacementMapFilter;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
    
    
    public class hoge extends Sprite
    {
        private var checkers:Bitmap = new Bitmap();
        
        private var canvas:Sprite = new Sprite();
        private var g:Graphics;
        
        private var dmf:DisplacementMapFilter = new DisplacementMapFilter();
        private var dmfdd:Function;
        
        private var ripples:Ripple;
        private var ir:Number;
        
        private var wz:int;
        private var hi:int;
//      Size of checkerboard; higher values create larger checks, while lower create smaller checks.    
        private var checkSize:int = 44;
                
        
        public function hoge()
        {
            wz = stage.stageWidth;
            hi = stage.stageHeight;
            
            var check:BitmapData = new BitmapData(checkSize, checkSize, true, 0);
            var rt:Rectangle     = new Rectangle(0, 0, checkSize / 2, checkSize / 2);
            check.fillRect(rt, 0xFF000000);
            rt.x = rt.y = rt.width;
            check.fillRect(rt, 0xFF000000);
            
            g = canvas.graphics;
            
            var mx:Matrix = new Matrix();
            mx.createGradientBox(wz, hi, Math.PI / 2);
            g.beginGradientFill("radial", [0xFFFFFF, 0x404040], [1, 1], [0, 255], mx);
            g.drawRect(0, 0, wz, hi);
            g.beginBitmapFill(check);
            g.drawRect(0, 0, wz, hi);
            
            var checkersData:BitmapData = new BitmapData(wz, hi, true);
            checkersData.draw(canvas);
            
            checkers.bitmapData = checkersData;
            addChild(checkers);
            
            g.clear();
            g.beginFill(0x000080);
            g.drawRect(0, 0, wz, hi);
            
            dmf.mapBitmap  = new BitmapData(wz, hi, false, 0x000080);
            dmf.componentX = dmf.componentY = 4;  // blue channel
            dmf.scaleX     = dmf.scaleY     = 100;
            dmf.mode       = "ignore";
            dmfdd          = dmf.mapBitmap.draw;
            //addChild(new Bitmap(dmf.mapBitmap));  // for debug
            
            Ripple.wz = wz;
            Ripple.hi = hi;
            ripples   = new Ripple();
            ir        = Ripple.ir;
            
            stage.addEventListener(MouseEvent.CLICK, clickListener);
        }
        
        
        private function clickListener(e:MouseEvent):void
        {
            var r:Ripple = ripples;
            var prev:Ripple;
            
            do {
                if (!r.isActive) break;
                prev = r;
            } while (r = r.next);
            
            if (!r) r = prev.next = new Ripple();
//||||         r.x       =  The X value of the PoC  
//||||         r.y       =  The Y value of the PoC                          
               r.x       =  e.stageX;
               r.y       =  e.stageY;
            
//||           FluidLens CoEfficient (Fc).  In the given equation:      
//||           (Fc)      =   FluidLens CoEfficient
//||           (scX)     =   scaleX Value of displacement
//||           (scY)     =   scaleY Value of displacement
//||           r.scX     =   Fc  =  r.scY
//||           ...A negative value creates a reverse ripple effect, bringing the wave towards the click, and then back out again
//||           ...A positive value creates a standard ripple, where the ripple eminates outward from PoC (point of click).
            r.scaleX     =   r.scaleY   = -4;
            r.isActive   =   true;
            canvas.addChild(r);
            
            addEventListener(Event.ENTER_FRAME, update);
        }
        
        
        private function update(e:Event):void
        {
            var r:Ripple   = ripples;
            var ex:Boolean = false;
            
            do {
                if (r.isActive) {
                    ex = true;
                    
                    var s:Number = r.scaleX = r.scaleY += 0.025;
                    r.alpha      = 1 - s / ir;
                    
                    if (s > ir) {
                        r.isActive = false;
                        canvas.removeChild(r);
                    }
                }
            } while (r = r.next);
            
            dmfdd(canvas);
            checkers.filters = [dmf];
            
            if (!ex) removeEventListener(Event.ENTER_FRAME, update);
        }
    }
}


import flash.display.Shape;
import flash.geom.Matrix;

class Ripple extends Shape
{
    public static var wz:int;
    public static var hi:int;
    public static var ir:Number;
    
    private static var b:uint       = 0xff9900;
    private static var k:uint       = 0xff9900;
    private static var colors:Array = [  b,   b,   k,   b,   b];
    private static var alphas:Array = [  0, 0.2, 0.4, 0.8,   0];
    private static var ratios:Array = [205, 225, 240, 250, 255];
    private static var mx:Matrix;
    
    public var isActive:Boolean = false;
    public var next:Ripple;
    
    
    public function Ripple()
    {
        if (!mx) {
            mx = new Matrix();
            mx.createGradientBox(wz, hi, 0, -wz / 2, -hi / 2);
            ir = ratios[ratios.length - 1] / ratios[0] * 2.8284;
        }
        
        graphics.beginGradientFill("radial", colors, alphas, ratios, mx);
        graphics.drawRect( -wz / 2, -hi / 2, wz, hi);
    }
}