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

forked from: DisplacementMapFilter 球

マウスドラッグで大きく
// forked from miniapp's 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://miniapp.org/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;
		}
	}
}