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

DisplacementMapFilter 球

マウスドラッグで大きく
/**
 * マウスドラッグで大きく
 */
package {
    
    import com.flashdynamix.utils.SWFProfiler;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.BitmapFilter;
    import flash.filters.BitmapFilterQuality;
    import flash.filters.DisplacementMapFilter;
    import flash.filters.DisplacementMapFilterMode;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.system.System;
    
    [SWF(backgroundColor="0xFFFFFF", width="465", height="465", frameRate="60")]
    public class Main6_5 extends Sprite {
        
        private static const WIDTH_STAGE:uint = 465;
        private static const HEIGHT_STAGE:uint = 465;
        
        public function Main6_5() {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private var _jpeg:Bitmap;
        private var _canvas:Sprite = new Sprite();
        private var _nowDmfsValue:uint = 0;
        private var _dmfs:Vector.<DisplacementMapFilter> = new Vector.<DisplacementMapFilter>();
        private var _radiuses:Vector.<Number> = new Vector.<Number>();
        
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            SWFProfiler.init(this);
            
                        Wonderfl.capture_delay( 3 );

            var context:LoaderContext = new LoaderContext();
            context.checkPolicyFile = true;
            
            var loader:Loader = new Loader();
            loader.load(new URLRequest("http://dust.heteml.jp/wonderfl/image/beck.jpg"), context);
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function():void { 
                _jpeg = Bitmap(loader.content);
                loader.contentLoaderInfo.removeEventListener(this, arguments.callee);
                start();
            });
        }
        
        private function start():void {
            _canvas.addChild(_jpeg);
            _canvas.x = (WIDTH_STAGE - _canvas.width) / 2;
            _canvas.y = (HEIGHT_STAGE - _canvas.height) / 2;
            addChild(_canvas);
            
            var radius:Number = 50;
            var dmf:DisplacementMapFilter = createDMF(radius);
            _radiuses.push(radius);
            _dmfs.push(dmf);
            
            radius = 100;
            dmf = createDMF(radius);
            _radiuses.push(radius);
            _dmfs.push(dmf);
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDowHander);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHander);
        }
        
        private function createDMF(radius:Number):DisplacementMapFilter {
            var mapBitmap:BitmapData = new BitmapData(radius * 2, radius * 2, false);
            var maxDistance:Number = radius / 2;//適当。適宜調整
            var dmf:DisplacementMapFilter = new DisplacementMapFilter(
                mapBitmap,
                new Point(),
                BitmapDataChannel.BLUE,//x方向の移動に使う色
                BitmapDataChannel.GREEN,//y方向の移動に使う色
                maxDistance, 
                maxDistance, 
                DisplacementMapFilterMode.COLOR
            );
            
            var yMax:int = radius * 2;
            var xMax:int = radius * 2;
            var center:Number = radius;
            mapBitmap.lock();
            for (var yy:int = 0; yy < yMax; ++yy) {
                for (var xx:int = 0; xx < xMax; ++xx) {
                    var dx:Number = xx - center;
                    var dy:Number = yy - center;
                    var distance:Number = Math.sqrt(dx * dx + dy * dy);
                        
                    if (distance <= radius) { 
                        //座標変換公式
                        //http://kenpei-web.hp.infoseek.co.jp/math/coordinates/
                        //中心に近づくほど90度(Math.PI / 2)になるようにする。
                        var rate:Number = distance / radius;
                        var theta:Number = (Math.PI / 2) * rate;
                        var phi:Number = Math.atan2(dy, dx);
                        var toX:Number = (radius * Math.sin(theta) * Math.cos(phi)) + center;
                        var toY:Number = (radius * Math.sin(theta) * Math.sin(phi)) + center;
                        
                        var colorX:Number = getColor(xx - toX, dmf.scaleX);
                        var colorY:Number = getColor(yy - toY, dmf.scaleY);
                        var color:uint = colorY << 8 | colorX;
                    }
                    else {
                        //何も変化しない色
                        color = 0x80808080;
                    }
                    mapBitmap.setPixel(xx, yy, color);
                }
            }
            mapBitmap.unlock();
            return dmf;
        }
        
        /**
         * @param    diff 動かしたい距離
         * @param    scale 取り得る値の最大値
         * @return
         */
        private function getColor(diff:Number, scale:Number):uint {
            return Math.round((diff * 0x100) / scale) + 0x80;
        }
        
        private function enterFrameHandler(e:Event):void {
            var dmf:DisplacementMapFilter = _dmfs[_nowDmfsValue];
            
            //マウス中心に動かす
            var p:Point = dmf.mapPoint;
            p.x = _canvas.mouseX - _radiuses[_nowDmfsValue];
            p.y = _canvas.mouseY - _radiuses[_nowDmfsValue];
            dmf.mapPoint = p;
            
            _jpeg.filters = [dmf];
        }
        
        private function mouseUpHander(e:MouseEvent):void {
            _nowDmfsValue = 0;
        }
        
        private function mouseDowHander(e:MouseEvent):void {
            _nowDmfsValue = 1;
        }
    }
}