forked from: forked from: Noize RollOver
/**
* Copyright no48 ( http://wonderfl.net/user/no48 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/XlGk
*/
// forked from es335dotr's forked from: Noize RollOver
// forked from kkeisuke's Noize RollOver
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;
// import net.hires.debug.Stats;
/**
* DisplacementMapFilter の練習。
* 下記で紹介されているエフェクトや、その下のサイトのオンマウス時のエフェクトを
* 再現したかったのですが・・・ほど遠い結果です。
* http://www.shin-go.net/motionlab/?p=127
* http://www.flashmania.jp/
*
* 置き換えマップデータの作り方など、下記を参考にさせて頂きました。ありがとうございます!
* (全然違うモノになったので、fork という形は控えさせて頂きました。)
* http://wonderfl.net/code/9897f9707a2bcb5543dc0af14dc572a45c4186dd
*/
[SWF(backgroundColor = 0x000000, frameRate = 40, width = 465, height = 465)]
public class NoizeRollOver extends Sprite
{
private static const URL:String = "http://assets.wonderfl.net/images/related_images/5/5f/5fd9/5fd907386c2c4584f449e1c10a37fc8d68fe7060";
private static const MAP_NUM:int = 3;
private static const STRONG_X:int = 500;
private static const STRONG_Y:int = 50;
private static const VX:int = 10;
private var dmf:DisplacementMapFilter;
private var sp:Sprite;
private var maps:/*BitmapData*/Array;
private var mapsLen:int;
private var centerX:int;
private var centerY:int;
private var scaleVX:int;
public function NoizeRollOver()
{
addEventListener(Event.ADDED_TO_STAGE , added);
}
private function added(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, added);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
init();
}
private function init():void
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE , complete);
loader.load(new URLRequest(URL), new LoaderContext(true));
}
private function complete(e:Event):void
{
var loaderInfo:LoaderInfo = e.target as LoaderInfo;
loaderInfo.removeEventListener(Event.COMPLETE , complete);
var bm:Bitmap = loaderInfo.content as Bitmap;
// 置き換えマップデータの作成
createMapBM(bm);
// 読み込んだ画像を配置。
setUpDO(bm);
}
private function createMapBM(bm:Bitmap):void
{
maps = [];
// 一応、3パターン作るようにしたが、1パターンでも良いかもしれない。
for (var i:int = 0; i < MAP_NUM; i++)
{
var mapBD:BitmapData = new BitmapData(bm.width, bm.height, false, 0);
// 効果があるかは分かりませんが、念のために。
mapBD.lock();
// グレースケールでノイズを描く
mapBD.noise((Math.random() * 10) >> 0, 0, 255, 7, true);
// 横方向にスクロールさせて横縞を作る。
var mapW:int = mapBD.width;
for (var j:int = 0; j < mapW; j++)
{
// 個々の値を変えると、他の表現が出来る。縦縞、斜めなど。
mapBD.scroll(1, 0);
}
mapBD.unlock();
maps[i] = mapBD;
}
mapsLen = maps.length;
}
private function setUpDO(bm:Bitmap):void
{
sp = new Sprite();
sp.addChild(bm);
centerX = (stage.stageWidth - sp.width) >> 1;
centerY = (stage.stageHeight - sp.height) >> 1;
sp.x = centerX;
sp.y = centerY;
sp.buttonMode = true;
sp.addEventListener(MouseEvent.ROLL_OVER, over);
addChild(sp);
// 置き換えマップデータの確認用
/*var mapBm:Bitmap = new Bitmap(maps[0]);
mapBm.x = stage.stageWidth - mapBm.width;
addChild(mapBm);*/
//addChild(new Stats());
// mapBitmap は後で入れる。
// componentX は何色でもいい?
// mode で微妙に見た目が変わる。とりあえず、"IGNORE"
dmf = new DisplacementMapFilter(null, new Point(0, 0), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE, STRONG_X, STRONG_Y, DisplacementMapFilterMode.IGNORE);
}
private function over(e:MouseEvent):void
{
reset(true);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
// フィルター取り出し
var fil:DisplacementMapFilter = sp.filters[0];
scaleVX += VX;
fil.scaleX -= scaleVX;
// 置き換えマップデータを選択。
fil.mapBitmap = maps[(Math.random() * mapsLen) >> 0];
// フィルター再適用
sp.filters = [fil];
// 適当に・・・。なんとなく点滅させるため。visible が良かったかな?
sp.alpha = sp.alpha == 0 ? 1 : 0;
// 収まったら止める。
if (fil.scaleX <= 0)
{
reset(false);
}
}
private function reset(active:Boolean):void
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
sp.x = centerX;
sp.y = centerY;
sp.alpha = active ? 0 : 1;
sp.filters = [dmf];
scaleVX = 0;
}
}
}