Ripple
/**
* Copyright takumi0125 ( http://wonderfl.net/user/takumi0125 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uduO
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.ConvolutionFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
[SWF(backgroundColor = "0xffffff", frameRate = "60")]
public class Main extends Sprite {
private var _mainBitmap:Bitmap; //メインのBitmap
private var _mainBitmapData:BitmapData; //メインのBitmapData
private var _mainShape:Shape; //メインのShape
private var _mainGraphics:Graphics; //メインのGraphics
private var _bitmapRect:Rectangle; //ビットマップの範囲
private var _bitmapDataWidth:Number; //ビットマップの横幅
private var _bitmapDataHeight:Number; //ビットマップの縦幅
private var _checkMaterialBitmapData:BitmapData; //チェックパターン用のBitmapData
private var _checkMaterialShape:Shape; //チェックパターン用のShape
private var _checkMaterialMatrix:Matrix; //チェックパターン用のMatrix
private var _bufferBitmapData1:BitmapData; //波紋フィルタ生成用のBitmapDataその1
private var _bufferBitmapData2:BitmapData; //波紋フィルタ生成用のBitmapDataその2
private var _defBitmapData:BitmapData; //波紋フィルタソース用のBitmapData
private var _bufferRect:Rectangle; //波紋フィルタ用のRectagle
private var _rippleCircle:Shape; //波紋の円
private var _originPoint:Point; //原点のPoint
private var _rippleFilter:DisplacementMapFilter; //波紋フィルタ (DisplacementMapFilter)
private var _convolitionFilter:ConvolutionFilter; //波紋生成のためのConvolutionFilter
private var _colourTransform:ColorTransform; //波紋生成のためのColorTransform
private var _matrix:Matrix; //波紋フィルタ用のMatrix
private const _SCALE:Number = 1 / 4; //フィルタのサイズ
private const _DISPLACEMENT_MAP_FILTER_SCALE:Number = 30; //DisplacementMapFilterのscale
private const _RIPPLE_RADIUS:Number = 10; //波紋生成時の半径
private const _CHECK_PATTERN_WIDTH:Number = 31; //チェックパターンのサイズ
//constructor
public function Main() {
_init();
}
//イニシャライズ
private function _init():void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT
//メインのビットマップ
_mainBitmap = new Bitmap();
addChild(_mainBitmap);
//メイン部分のイニシャライズ
_mainShape = new Shape();
_mainGraphics = _mainShape.graphics;
_checkMaterialMatrix = new Matrix();
_checkMaterialShape = new Shape();
var checkMaterialGraphics:Graphics = _checkMaterialShape.graphics;
checkMaterialGraphics.beginFill(0xaacf53);
checkMaterialGraphics.drawRect(0, 0, _CHECK_PATTERN_WIDTH, _CHECK_PATTERN_WIDTH);
checkMaterialGraphics.drawRect(_CHECK_PATTERN_WIDTH, _CHECK_PATTERN_WIDTH, _CHECK_PATTERN_WIDTH, _CHECK_PATTERN_WIDTH);
checkMaterialGraphics.endFill();
_checkMaterialBitmapData = new BitmapData(_CHECK_PATTERN_WIDTH * 2, _CHECK_PATTERN_WIDTH * 2);
_checkMaterialBitmapData.draw(_checkMaterialShape);
//波紋用のデータをイニシャライズ
_originPoint = new Point();
_convolitionFilter = new ConvolutionFilter(3, 3, [0.5, 1, 0.5, 1, 0, 1, 0.5, 1, 0.5], 3);
_colourTransform = new ColorTransform(1, 1, 1, 1, 128, 128, 128);
_rippleCircle = new Shape();
var circleGraphics:Graphics = _rippleCircle.graphics;
circleGraphics.beginFill(0xff);
circleGraphics.drawCircle(0, 0, _RIPPLE_RADIUS * _SCALE);
circleGraphics.endFill();
_matrix = new Matrix();
_resizeHandler();
//リサイズ処理
stage.addEventListener(Event.RESIZE, _resizeHandler);
//フレームごとの処理
stage.addEventListener(Event.ENTER_FRAME, _enterFrameHandler);
//マウスを動かした際の処理
stage.addEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveHandler);
}
//リサイズ処理
private function _resizeHandler(e:Event = null):void {
_bitmapDataWidth = stage.stageWidth;
_bitmapDataHeight = stage.stageHeight;
_bitmapRect = new Rectangle(0, 0, _bitmapDataWidth, _bitmapDataHeight);
//メインのビットマップ
_checkMaterialMatrix.identity();
_checkMaterialMatrix.translate((_bitmapDataWidth - _CHECK_PATTERN_WIDTH) / 2, (_bitmapDataHeight - _CHECK_PATTERN_WIDTH) / 2);
_mainGraphics.clear();
_mainGraphics.beginBitmapFill(_checkMaterialBitmapData, _checkMaterialMatrix);
_mainGraphics.drawRect(0, 0, _bitmapDataWidth, _bitmapDataHeight);
_mainGraphics.endFill();
if(_mainBitmapData) _mainBitmapData.dispose();
_mainBitmapData = new BitmapData(_bitmapDataWidth, _bitmapDataHeight, false, 0xffffffff);
_mainBitmapData.draw(_mainShape);
//波紋処理
if(_bufferBitmapData1) _bufferBitmapData1.dispose();
_bufferBitmapData1 = new BitmapData(_bitmapDataWidth * _SCALE, _bitmapDataHeight * _SCALE, false, 0x000000);
if(_bufferBitmapData2) _bufferBitmapData2.dispose();
_bufferBitmapData2 = new BitmapData(_bufferBitmapData1.width, _bufferBitmapData1.height, false, 0x000000);
if(_defBitmapData) _defBitmapData.dispose();
_defBitmapData = new BitmapData(_bitmapDataWidth, _bitmapDataHeight, false, 0xff000000);
_bufferRect = new Rectangle(0, 0, _bufferBitmapData1.width, _bufferBitmapData1.height);
_rippleFilter = new DisplacementMapFilter(_defBitmapData, _originPoint, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE, _DISPLACEMENT_MAP_FILTER_SCALE, _DISPLACEMENT_MAP_FILTER_SCALE, DisplacementMapFilterMode.WRAP);
_matrix.identity();
_matrix.scale(_defBitmapData.width / _bufferBitmapData1.width, _defBitmapData.height / _bufferBitmapData1.height);
_mainBitmap.bitmapData = _mainBitmapData;
}
//フレームごとの処理
private function _enterFrameHandler(e:Event = null):void {
var temp:BitmapData = _bufferBitmapData2.clone();
_bufferBitmapData2.applyFilter(_bufferBitmapData1, _bufferRect, _originPoint, _convolitionFilter);
_bufferBitmapData2.draw(temp, null, null, BlendMode.SUBTRACT, null, false);
_defBitmapData.draw(_bufferBitmapData2, _matrix, _colourTransform, null, null, true);
_rippleFilter.mapBitmap = _defBitmapData;
temp.dispose();
temp = _bufferBitmapData1;
_bufferBitmapData1 = _bufferBitmapData2;
_bufferBitmapData2 = temp;
_mainBitmap.filters = [_rippleFilter];
}
//マウスを動かした際の処理
private function _mouseMoveHandler(e:MouseEvent):void {
var stageX:Number = e.stageX;
var stageY:Number = e.stageY;
_bufferBitmapData1.draw(_rippleCircle, new Matrix(1, 0, 0, 1, stageX * _SCALE, stageY * _SCALE));
}
}
}