forked from: bending filter
forked from:http://wonderfl.net/c/mLWT
this effect is very good:)))
/**
* Copyright shen_0_ ( http://wonderfl.net/user/shen_0_ )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7vqW
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.TextField;
[SWF(width='465', height='465', backgroundColor="#123456")]
public class Bending extends Sprite {
public static const W:int=465;
public static const H:int=465;
public static const SIZE_BEND:int=120;
public static const SIZE_BEND_h:int=SIZE_BEND * 0.5;
private var sp:Sprite=new Sprite();
//bending
private var gradient_bmp:BitmapData;
private var gradient_bm:Bitmap;
private var dm_filter:DisplacementMapFilter;
private var dm_fs:Array=[];
//bend list
private var tick:int=0;
private var bendLen:int=0;
private var maxLen:int=9;
private var bendList:Array=[];
private var bendPool:Array=[]; //object pool
private var filterList:Array=[]; //DisplacementMapFilter filter array
public function Bending() {
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
//material
var mat:BitmapData=new BitmapData(128, 20, false, 0x333333);
var t:TextField=new TextField();
t.text="DisplacementMapFilter";
t.width=t.textWidth + 10;
mat.draw(t);
var mat2:BitmapData=new BitmapData(64, 20, false, 0xaaaaaa);
t.text="Bending";
t.width=t.textWidth + 10;
mat2.draw(t);
var m:Matrix=new Matrix();
m.rotate(1);
sp.graphics.beginBitmapFill(mat2, m);
sp.graphics.drawRect(0, 0, W, H);
sp.graphics.beginBitmapFill(mat);
sp.graphics.drawRect(150, 50, 200, 100);
sp.graphics.drawRect(180, 250, 200, 100);
sp.graphics.drawRect(370, 100, 100, 100);
sp.graphics.drawRect(0, 300, 100, 50);
sp.graphics.endFill();
//bending sample
createBitmapFilter();
addChild(sp);
addChild(gradient_bm);
stage.addEventListener(Event.ENTER_FRAME, loop);
}
//enter frame
private function loop(e:Event):void {
var b:BendWave;
var i:int;
if (tick < 10) {
tick++;
} else {
tick=0;
createBend(Math.random() * W, Math.random() * H);
if (bendLen > maxLen) {
var l:int=bendLen - maxLen;
for (i=0; i < l; i++) {
b=bendList[i];
b.toEnd();
}
}
}
//trace("filter nums:",bendLen)
for (i=0; i < bendLen; i++) {
b=bendList[i];
if (b.isEnd()) {
filterList.splice(i, 1);
bendList.splice(i, 1);
bendLen--;
i--;
setBend(b);
removeChild(b);
} else {
b.update()
}
}
sp.filters=filterList;
}
/**
* bending sample
*/
private function createBitmapFilter():void {
gradient_bmp=new BitmapData(SIZE_BEND, SIZE_BEND, false, 0x8080);
const hsize_noSqrt:int=SIZE_BEND_h * SIZE_BEND_h;
const hlsize:int=int((SIZE_BEND - 1) * 0.5);
//扭曲模板
for (var y:int=0; y < SIZE_BEND; y++) {
var GapY:int=hlsize - y;
for (var x:int=0; x < SIZE_BEND; x++) {
var GapX:int=hlsize - x;
var distance:Number=GapX * GapX + GapY * GapY;
if (distance < hsize_noSqrt) {
var ratio:Number=1 - distance / hsize_noSqrt;
ratio=Math.sin(0.5 * Math.PI * ratio);
ratio=0.5 - 0.5 * Math.cos(Math.PI * ratio);
gradient_bmp.setPixel(x, y, (GapX * ratio + 0x80) << 8 | (GapY * ratio + 0x80));
}
}
}
gradient_bm=new Bitmap(gradient_bmp);
}
private function createBend(x:int, y:int):void {
bendLen++;
var b:BendWave=getBend();
b.setPos(x, y);
bendList.push(b);
filterList.push(b.getBend());
addChild(b);
}
/**
* object pool function
*/
private function getBend():BendWave {
var b:BendWave=bendPool.shift();
if (b) {
return b;
}
return new BendWave(gradient_bmp);
}
private function setBend(b:BendWave):void {
b.reset();
bendPool.push(b);
}
}
}
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Shape;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Point;
class BendWave extends Shape {
private var size:Number=0;
private var wait:int=0;
private var zoomIn:Boolean=true;
private var _end:Boolean=false;
//filter
private var bend:DisplacementMapFilter;
private const bScale:Number=128;
//temp
private var oldsize:Number=0;
public function BendWave(bmp:BitmapData):void {
var componentX:uint=BitmapDataChannel.GREEN;
var componentY:uint=BitmapDataChannel.BLUE;
var mode:String=DisplacementMapFilterMode.CLAMP;
var color:uint=0;
var alpha:Number=0;
bend=new DisplacementMapFilter(bmp,
null,
componentX,
componentY,
bScale,
bScale,
mode,
color,
alpha);
this.graphics.lineStyle(0, 0, 0.5);
this.graphics.beginFill(0x7BAFE9, 0.1);
this.graphics.drawCircle(0, 0, Bending.SIZE_BEND_h);
this.graphics.endFill();
reset();
}
//get
public function getBend():DisplacementMapFilter {
return bend;
}
public function isEnd():Boolean {
return _end;
}
//step
public function update():void {
if (wait < 10) {
wait++;
}
if (wait >= 10 && !zoomIn) {
size+=(0 - size) * 0.3;
if (size < 1) {
_end=true;
}
} else {
size+=(Bending.SIZE_BEND - size) * 0.3;
}
if (oldsize != size) {
oldsize=size;
this.width=size;
this.height=size;
bend.scaleX=bScale * size / Bending.SIZE_BEND;
bend.scaleY=bScale * size / Bending.SIZE_BEND;
}
}
//control
public function reset():void {
zoomIn=true;
_end=false;
size=0;
wait=0;
this.width=0;
this.height=0;
oldsize=-1;
}
public function setPos(x:int, y:int):void {
var p:Point=bend.mapPoint;
p.x=x - Bending.SIZE_BEND_h;
p.y=y - Bending.SIZE_BEND_h;
bend.mapPoint=p;
this.x=x;
this.y=y;
}
public function toEnd():void {
zoomIn=false;
}
}