ActionScript3でゆらゆら
AS3で画像をゆらゆらさせてみた。
元画像はこれ↓
この画像をゆらゆらさせるとこんな感じ。
わかりにくいけど、一応ゆらゆら動いてます。
以下、スクリプト。
Root.as
package { import flash.display.Sprite; import flash.display.StageAlign; public class Root extends Sprite { public function Root():void { stage.scaleMode = "noScale"; stage.align = StageAlign.TOP_LEFT; graphics.beginFill(0x444444); graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); graphics.endFill(); addChild(new Base()); } } }
Base.as
package { import flash.display.Sprite; import flash.display.Loader; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.geom.Point; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.events.Event; import flash.net.URLRequest; public class Base extends Sprite { public static const IMAGE_WIDTH:Number = 400; public static const IMAGE_HEIGHT:Number = 300; public static const BITMAPDATA_WIDTH:Number = IMAGE_WIDTH; public static const BITMAPDATA_HEIGHT:Number = IMAGE_HEIGHT; public static const OFFSET:Number = 0; public static const BASE:Number = 1 / 8; public static const PERLIN_OCTAVES:Number = 6; public static const COLOR_CHANNEL:Number = BitmapDataChannel.BLUE | BitmapDataChannel.GREEN; public static const SCALE:Number = 15; private var bmpData:BitmapData; private var point:Point; public function Base():void { // PointクラスとBitmapDataクラスは毎フレーム生成する必要はない this.point = new Point(OFFSET, OFFSET); this.bmpData = new BitmapData(BITMAPDATA_WIDTH, BITMAPDATA_HEIGHT); // 画像データ読み込み var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); loader.load(new URLRequest("photo.jpg")); loader.scaleX = 0.5; loader.scaleY = 0.5; addChild(loader); } private function completeHandler(e:Event):void { // 画像の読み込みが完了したらイベントハンドラーを登録 addEventListener(Event.ENTER_FRAME, enterFrameHandler); } private function enterFrameHandler(e:Event):void { this.bmpData.perlinNoise(BITMAPDATA_WIDTH * BASE, BITMAPDATA_HEIGHT * BASE, PERLIN_OCTAVES, Math.floor(Math.random() * 10), false, true, COLOR_CHANNEL, false); var displacementMap:DisplacementMapFilter = new DisplacementMapFilter(this.bmpData, this.point, BitmapDataChannel.BLUE, BitmapDataChannel.GREEN, SCALE, SCALE, DisplacementMapFilterMode.CLAMP); filters = [displacementMap]; } } }
ゆらゆらさせている処理はBaseクラスのenterFrameHandlerメソッド内。
this.bmpData.perlinNoise(BITMAPDATA_WIDTH * BASE, BITMAPDATA_HEIGHT * BASE, PERLIN_OCTAVES, Math.floor(Math.random() * 10), false, true, COLOR_CHANNEL, false); var displacementMap:DisplacementMapFilter = new DisplacementMapFilter(this.bmpData, this.point, BitmapDataChannel.BLUE, BitmapDataChannel.GREEN, SCALE, SCALE, DisplacementMapFilterMode.CLAMP); filters = [displacementMap];
まずBitmapDataクラスのperlinNoiseメソッドでノイズイメージを生成。
この処理で↓こんなBitmapDataが生成される。
これを置き換え用BitmapDataとしてDisplaycementMapFilterを生成。
最後にBaseクラスのfiltersに、生成したDisplacementMapFilterをセットしてあげれば、画像がゆらゆらしてくれる。
DisplacementMapFilterクラスの生成について、少し補足します。
var displacementMap:DisplacementMapFilter = new DisplacementMapFilter(this.bmpData, this.point, BitmapDataChannel.BLUE, BitmapDataChannel.GREEN, SCALE, SCALE, DisplacementMapFilterMode.CLAMP);
ここで、3番目と4番目の引数に注目してみましょう。
3番目の引数で青、4番目の引数で緑を指定しています。
3番目の引数は、X方向にどのカラーチャネルを使用するか、
4番目の引数は、Y方向にどのカラーチャネルを使用するかを指定します。
ここで、↓先ほどの変な画像。
この画像の青の部分を使用してX方向に置き換え、緑の部分を使用してY方向に置き換えとなります。
これを毎フレーム処理する事で、画像がゆらゆらするようになるわけですね。