forked from: DisplacementMapFilter with perlineNoise (GradientBox)
DisplacementMapFilter with GradientBox
GradientBox を DisplacementMapFilter に適用して、
マウスクリックに応じて写真をぐにゃぐにゃさせます。
左が DisplacementMapFilter によって変形するイメージ、
右がイメージを変形させている Filter に適用されている GradientBox
画像読み込みは 5ivestar さんの Proxy を使わせていただきました。
wonderfl.kayac.com/code/e40aae6e65d9f379f7cd3684d40eb710a7701a2d
// forked from Aquioux's DisplacementMapFilter with perlineNoise
// DisplacementMapFilter with GradientBox
// GradientBox を DisplacementMapFilter に適用して、
// マウスクリックに応じて写真をぐにゃぐにゃさせます。
// 左が DisplacementMapFilter によって変形するイメージ、
// 右がイメージを変形させている Filter に適用されている GradientBox
//
// 画像読み込みは 5ivestar さんの Proxy を使わせていただきました。
// wonderfl.kayac.com/code/e40aae6e65d9f379f7cd3684d40eb710a7701a2d
package {
/**
* @author YOSHIDA, Akio
*/
import flash.display.Sprite;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.IEventDispatcher;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.system.Security;
import caurina.transitions.Tweener;
import caurina.transitions.properties.FilterShortcuts;
[SWF(width="465", height="465", frameRate="60", backgroundColor="#000000")]
public class Main extends Sprite {
private var loader:Loader; // ローダー
private var loading:TextField; // ナウローディング表示
// 表示イメージ
private var displayBm:Bitmap;
// 置き換えマップ可視化
private var mapBm:Bitmap;
// 置き換えマップ
private var displacementMap:GradientMap;
// DisplacementMapFilter
private var dmf:EasyDMF;
// DisplacementMapFilter 用パラメータ
private var sx : Number = 0;
private var sy : Number = 0;
private var fx : Number = 1;
private var fy : Number = 1;
public function Main():void {
FilterShortcuts.init();
Security.loadPolicyFile("http://5ivestar.org/proxy/crossdomain.xml");
// Loader 生成
loader = new Loader();
// イベントリスナー登録
configureListeners(loader.contentLoaderInfo);
// ロード開始
loader.load(new URLRequest("http://5ivestar.org/proxy/http://homepage3.nifty.com/aquioux/swf/as3/wonderfl/aquioux001.jpg"));
// ナウローディング
loading = new TextField();
loading.defaultTextFormat = new TextFormat("_sans", 24, 0xffffff);
loading.text = "Now Loading...";
loading.autoSize = "left";
loading.x = (stage.stageWidth - loading.width) / 2;
loading.y = (stage.stageHeight - loading.height) / 2;
addChild(loading);
}
// イベントリスナー登録
private function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandler);
}
// 読み込み完了時のイベントハンドラ
private function completeHandler(e:Event):void {
create();
}
private function create():void {
removeChild(loading);
var explain:TextField = new TextField();
explain.defaultTextFormat = new TextFormat("_sans", 16, 0xffffff);
explain.text = "左側の画像上でマウスを押したり離したりしてください。\nマウスをドラッグしても良いかも知れません。";
explain.autoSize = "left";
explain.x = 10;
explain.y = 210;
addChild(explain);
// 表示イメージ
var w:uint = loader.width;
var h:uint = loader.height;
var margin:uint = 0;
var bmd:BitmapData = new BitmapData(w-margin*2, h-margin*2, false, 0x000000);
bmd.draw(loader.content, new Matrix(1, 0, 0, 1, -margin, -margin));
displayBm = new Bitmap(bmd);
displayBm.x = margin;
displayBm.y = margin;
addChild(displayBm);
loader = null;
// 置き換えマップ可視化
mapBm = new Bitmap();
mapBm.x = w;
mapBm.y = 0;
addChild(mapBm);
// 置き換えマップと DisplacementMapFilter 生成
dmf = new EasyDMF(new GradientMap(w, h));
mapBm.bitmapData = dmf.filter.mapBitmap;
// イベントハンドラ
stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
}
// イベントハンドラ
private function mouseDownHandler(e:MouseEvent):void {
Tweener.removeAllTweens();
sx = 0;
sy = 0;
addEventListener(Event.ENTER_FRAME , onEnterFrameHandler);
}
private function mouseUpHandler( e:MouseEvent ):void {
removeEventListener(Event.ENTER_FRAME , onEnterFrameHandler);
motion();
}
private function onEnterFrameHandler( e:Event ):void {
var w:uint = displayBm.width / 2;
var h:uint = displayBm.height / 2;
(mouseX > w) ? fx = -1 : fx = 1 ;
(mouseY > h) ? fy = -1 : fy = 1 ;
sx += (2 * fx);
sy += (2 * fy);
dmf.filter.scaleX = sx;
dmf.filter.scaleY = sy;
displayBm.filters = [dmf.filter];
}
// 復元モーション
private function motion():void {
Tweener.addTween(
displayBm, {
_DisplacementMap_scaleX:0,
_DisplacementMap_scaleY:0,
time:(1024 / Math.abs(sx) + 1024 / Math.abs(sy)) * 0.5,
transition:"easeOutElastic"
}
);
}
}
}
// DisplacementMapFilter
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.geom.Point;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
class EasyDMF {
private var _filter:DisplacementMapFilter;
private var map:IDisplacementMap; // 置き換えマップ
public function EasyDMF(map:IDisplacementMap) {
this.map = map;
var scale:uint = 0;
_filter = new DisplacementMapFilter(
map.bitmapData,
new Point(0, 0),
BitmapDataChannel.RED,
BitmapDataChannel.RED,
scale,
scale,
DisplacementMapFilterMode.CLAMP
);
}
public function renew():void {
map.renew();
_filter.mapBitmap = map.bitmapData;
}
public function get filter():DisplacementMapFilter { return _filter; }
}
// DisplacementMap(GradientBox)
import flash.display.Shape;
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;
import flash.geom.Matrix;
class GradientMap implements IDisplacementMap {
private var _bitmapData:BitmapData;
private const GRAY:uint = 0x808080;
public function GradientMap(w:uint, h:uint) {
_bitmapData = new BitmapData(w, h, true, 0x00ffffff);
var colors:Array = [0x000000, 0xffffff];
var alphas:Array = [1, 1];
var ratios:Array = [0x00, 0xff];
var margin:uint = 25;
var mtx:Matrix = new Matrix(1, 0, 0, 1, margin, margin);
mtx.createGradientBox(w + margin * 2, h + margin * 2, 0, -margin, -margin);
var shp:Shape = new Shape();
shp.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, mtx, SpreadMethod.PAD, InterpolationMethod.RGB);
shp.graphics.drawRect(0, 0, w + margin * 2, h + margin * 2);
shp.graphics.endFill();
_bitmapData.draw(shp);
}
public function renew():void {}
public function get bitmapData():BitmapData { return _bitmapData; }
}
// interface of DisplacementMap
import flash.display.BitmapData;
interface IDisplacementMap {
function renew():void;
function get bitmapData():BitmapData;
}