forked from: drawTrianglesであそぼ - スライドエフェクトサンプル - モーフィング2

by s26 forked from drawTrianglesであそぼ - スライドエフェクトサンプル - モーフィング2 (diff: 8)
♥0 | Line 368 | Modified 2012-06-08 13:45:19 | MIT License
play

ActionScript3 source code

/**
 * Copyright s26 ( http://wonderfl.net/user/s26 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bM6T
 */

// forked from HaraMakoto's drawTrianglesであそぼ - スライドエフェクトサンプル - モーフィング2
package {
    import __AS3__.vec.Vector;
    
    import com.bit101.components.PushButton;
    
    import flash.display.Bitmap;
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.net.URLRequest;
    import flash.system.Security;
    
    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="40")]
    public class DrawMorphing2 extends Sprite
    {
        private var counter:int = 0;
        private var max:int = 0;
        private var distortList:Array = new Array();
        private var distort1:DistortUnit = new DistortUnit("http://wonderfl.net/img/common/logo.png","ML");
        private var distort2:DistortUnit = new DistortUnit("http://wonderfl.net/img/common/logo.png");
        private var distort3:DistortUnit = new DistortUnit("http://wonderfl.net/img/common/logo.png","MR");
        private var distort4:DistortUnit = new DistortUnit("http://wonderfl.net/img/common/logo.png","TR");
        private var distort5:DistortUnit = new DistortUnit("http://wonderfl.net/img/common/logo.png","MC");
        private var distort6:DistortUnit = new DistortUnit("http://wonderfl.net/img/common/logo.png","BL");
//        private var distort1:DistortUnit = new DistortUnit("data/train1.jpg","ML");
//        private var distort2:DistortUnit = new DistortUnit("data/train2.jpg");
//        private var distort3:DistortUnit = new DistortUnit("data/train3.jpg","MR");
//        private var distort4:DistortUnit = new DistortUnit("data/car_01.jpg","TR");
//        private var distort5:DistortUnit = new DistortUnit("data/car_03.jpg","MC");
//        private var distort6:DistortUnit = new DistortUnit("data/car_04.jpg","BL");
        private var current:DistortUnit;
        
        public function DrawMorphing2() {
            current = distort1;
            distortList.push( distort1 );
            distortList.push( distort2 );
            distortList.push( distort3 );
            distortList.push( distort4 );
            distortList.push( distort5 );
            distortList.push( distort6 );
            max = distortList.length;
            
            var i:int;
            for(i=0; i<max; i++) {
                var _tmp:DistortUnit = distortList[i];
                if(i==0) {
                    _tmp.setNext( distortList[max-1] );                    
                } else {
                    _tmp.setNext( distortList[i-1] );
                }
                addChild( _tmp );
                _tmp.setStartPos();
                _tmp.Distorter.alpha=0;
            }
            current.Distorter.alpha = 1;
            
            var btn:PushButton = new PushButton(this, 50,50,"slide", clickHandler);
        }
        private function clickHandler(event:MouseEvent):void {
            allStop();
            current.startRender(); //前の
            current.fadeOut();
            if(counter == max-1) {
                counter = 0;
                distortList[ 0 ].fadeIn();
                current = distortList[ 0 ];
            } else {
                distortList[ counter+1 ].fadeIn();
                current = distortList[ counter+1 ];
                counter++;
            }
            current.startRender(); //次の
        }
        private function allStop():void {
            var i:int;
            for(i=0; i<max; i++) {
                var _tmp:DistortUnit = distortList[i];
                _tmp.stopRender();
            }
        }
    }
    
}
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import __AS3__.vec.Vector;
    import flash.display.Bitmap;
    import flash.geom.Point;
    import flash.events.Event;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.core.easing.IEasing;
    import org.libspark.betweenas3.core.easing.CubicEaseOut;
    import org.libspark.betweenas3.easing.Cubic;
    import org.libspark.betweenas3.easing.Quint;

class DistortUnit extends Sprite {
    //頂点分割数
    private var cutNum:int = 3;
    //頂点ポイント配列
    private var PtArray:Array;
    private var loader:Loader = new Loader();
    private var bmp:Bitmap;
    //4点の配列
    private var pList:Array = new Array();
    //4点の描画レイヤー
    private var pLayerList:Array = new Array();
    //初期の座標
    private var firstPosList:Array = new Array();
    //Distorter
    public var Distorter:Distort = new Distort();
    private var _xMin:Number;
    private var _yMin:Number;
    private var _xMax:Number;
    private var _yMax:Number;
    private var _w:Number;
    private var _h:Number;
    private var _facePos:String = "MC";
    
    private var _nextDistort:DistortUnit;
    
    public function DistortUnit(_url:String, pos:String = "MC") {
        addChild(Distorter);
        _facePos = pos;
        
        for(var i:int=0; i<4; i++) {
            pLayerList.push(new Sprite());
            addChild(pLayerList[i]);
        }
        loader.load(new URLRequest(_url));
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComp);
    }
    public function setNext(d:DistortUnit):void {
        _nextDistort = d;
    }
    private function setPoints():void
    {
        //Distort.pointNumCulc:分割数に対応した頂点数を返す
        PtArray = new Array( Distort.pointNumCulc(cutNum) );
        var i:int;
        var len:int = PtArray.length;
        //頂点座標設定
        for(i=0; i<len; i++) {
            //4隅を保存する
            if(i==0||i==cutNum||i==len-1||i==len-1-cutNum) {
                PtArray[i] = new handleTouchPoint();
                pList.push(PtArray[i]);
            } else {
                PtArray[i] = new touchPoint();
            }
            addChild(PtArray[i]);
        }
        
        for(i=0; i<pList.length; i++) {
            pList[i].drawLayer = pLayerList[i];
            pList[i].build(0xFFFFFF);
        }
    }
    private function loadComp(e:Event):void
    {
        bmp = Bitmap(loader.content);
        _xMin = _yMin = 0;
        _xMax = bmp.width;
        _yMax = bmp.height;
        this.x = 464/2 - _xMax/2;
        this.y = 464/2 - _yMax/2;
        //頂点設定
        setPoints();
        //ディストーションクラス設定
        Distorter.setDistortion(cutNum, PtArray, bmp.bitmapData, _facePos);
        Distorter.render();
        addEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }
    
    public function startRender():void {
        if( !hasEventListener(Event.ENTER_FRAME) ) {
            addEventListener(Event.ENTER_FRAME, handleEnterFrame);
        }
    }
    public function stopRender():void {
        if( hasEventListener(Event.ENTER_FRAME) ) {
            removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
        }
    }
    
    private function handleEnterFrame(event:Event):void {
        Distorter.render();
    }
    
//--------------------------------------------------------------------------------//
//    パブリック メソッド
//--------------------------------------------------------------------------------//
    public function setStartPos():void {
        var i:int=0;
        for each(var p:touchPoint in PtArray) {
            p.x = _nextDistort.PtArray[i].baseX;
            p.y = _nextDistort.PtArray[i].baseY;
            i++;
        }
    }
    public function fadeOut():void {
        var i:int = 0;
        BetweenAS3.tween(Distorter,{alpha:0},null,1,Quint.easeOut).play();
    }
    
    public function fadeIn():void {
        var i:int = 0;
        var p:touchPoint;
        
        for each(p in PtArray) {
            p.x = _nextDistort.PtArray[i].baseX;
            p.y = _nextDistort.PtArray[i].baseY;
            BetweenAS3.delay(
                BetweenAS3.tween(p,{x:p.baseX,y:p.baseY},null,1,Quint.easeOut),
                0.0*i
            ).play();
            i++;
        }
        BetweenAS3.tween(Distorter,{alpha:1},null,1,Quint.easeOut).play();
    }
    
    
}
class Distort extends Sprite {
    //4×4分割のフィールド
    private var fieldMC:Sprite = new Sprite();
    private var cutNum:int; //頂点分割数
    private var vertNum:int; //頂点数
    private var slong:Number; //横縦幅
    private var vlong:Number; //頂点
    private var verticies:Vector.<Number>; //uvポイントMC
    private var ptArray:Array; //vertポイント配列
    private var vertPtArray:Array; //頂点番号
    private var indicies:Vector.<int>; //テクスチャ
    private var uvData:Vector.<Number>;
    private var bmd:BitmapData;
    public static var SSS:String = "SSS!";
    private var _facePosition:String = "MC"; //top bottom
    
    //コンストラクタ
    public function Distort() {}
    
    //頂点分割数と配列を得る
    public function setDistortion(c:int, vtArray:Array, _bmd:BitmapData, pos:String="MC"):void
    {
        addChild(fieldMC);
        bmd = _bmd;
        _facePosition = pos;
        slong = bmd.width;
        vlong = bmd.height;
        cutNum = c;
        vertPtArray = vtArray;
        setVertices();
    }
    
    //分割数に対応した頂点数を返す
    public static function pointNumCulc(n:int):int {
        var vnum:int = (n+1)*(n+1);
        return vnum;
    }
    
    //頂点設定
    public function setVertices():void
    {
        vertNum = (cutNum+1)*(cutNum+1);
        ptArray = new Array(vertNum);
        //ブロック単位
        var bUnit:Number = 1 / cutNum;
        var i:int; var t:int;
        //頂点座標をPointに設定
        for(i=0; i<cutNum+1; i++) {
            for(t=0; t<cutNum+1; t++) {
                ptArray[i*(cutNum+1)+t] = new Point(bUnit*t, bUnit*i);
                vertPtArray[i*(cutNum+1)+t].setPt( bUnit*t*slong,bUnit*i*vlong );
                
                //顔が上か、真ん中か、下かでかたよらせる
                var coefX:Number=0;
                var coefY:Number=0;
                switch(_facePosition) {
                    case "TL":
                        coefX = -bUnit*0.5;
                        coefY = -bUnit*0.5;
                        break;
                    case "TR":
                        coefX = bUnit*0.5;
                        coefY = -bUnit*0.5;
                        break;
                    case "TC":
                        coefX = 0;
                        coefY = -bUnit*0.5;
                        break;
                    case "ML":
                        coefX = -bUnit*0.5;
                        coefY = 0;
                        break;
                    case "MR":
                        coefX = bUnit*0.5;
                        coefY = 0;
                        break;
                    case "MC":
                        coefX = 0;
                        coefY = 0;
                        break;
                    case "BR":
                        coefX = bUnit*0.5;
                        coefY = bUnit*0.5;
                        break;
                    case "BL":
                        coefX = -bUnit*0.5;
                        coefY = bUnit*0.5;
                        break;
                    case "BC":
                        coefX = 0;
                        coefY = bUnit*0.5;
                        break;
                }
                if(i!=0&&i!=cutNum&&t!=0&&t!=cutNum) {
                    ptArray[i*(cutNum+1)+t].x += coefX;
                    ptArray[i*(cutNum+1)+t].y += coefY;
                    vertPtArray[i*(cutNum+1)+t].setPt( (bUnit*t+coefX)*slong,(bUnit*i+coefY)*vlong );
                }
            }
        }
        //vertice
        verticies = new Vector.<Number>(vertNum*2);
        //uvts
        uvData = new Vector.<Number>(vertNum*2);
        //indicies
        indicies = new Vector.<int>(cutNum*cutNum*6);
    }
    //テクスチャの反映
    public function render():void {
        var i:int; var t:int;
        for(i=0; i<vertNum; i++) {
            verticies[(i << 1)    ] = vertPtArray[i].x;
            verticies[(i << 1) + 1] = vertPtArray[i].y;
        }
        //uvts
        for(i=0; i<vertNum; i++) {
            uvData[(i << 1)    ] = ptArray[i].x;
            uvData[(i << 1) + 1] = ptArray[i].y;
        }
        //indicies
        for(i=0; i<cutNum; i++) {
            var iad:int = i*6;
            for(t=0; t<cutNum; t++) {
                var tad:int = t*6;
                indicies[iad*(cutNum)+tad] = t+i*(cutNum+1);
                indicies[iad*(cutNum)+tad+1] = t+1+i*(cutNum+1);
                indicies[iad*(cutNum)+tad+2] = t+(i+1)*(cutNum+1);
                indicies[iad*(cutNum)+tad+3] = t+1+i*(cutNum+1);
                indicies[iad*(cutNum)+tad+4] = t+(i+1)*(cutNum+1);
                indicies[iad*(cutNum)+tad+5] = t+1+(i+1)*(cutNum+1);
            }
        }
        fieldMC.graphics.clear();
        fieldMC.graphics.beginBitmapFill(bmd);
        fieldMC.graphics.drawTriangles(verticies, indicies, uvData);
        fieldMC.graphics.endFill();
    }
}

//各頂点のポイント
class touchPoint extends Sprite {
    public var baseX:Number;
    public var baseY:Number;
    public function touchPoint() {
        this.buttonMode = true;
        build();
        this.addEventListener(MouseEvent.MOUSE_DOWN,downHandler);
        this.addEventListener(MouseEvent.MOUSE_UP,upHandler);
    }
    public function setPt(_x:Number, _y:Number):void
    {
        this.x = _x;
        this.y = _y;
        baseX = _x;
        baseY = _y;
    }
    protected function downHandler(e:MouseEvent):void
    {
        this.startDrag();
    }
    protected function upHandler(e:MouseEvent):void {
        this.stopDrag();
    }
    public function build(col:Number=0xFF0000):void
    {
//        this.graphics.clear();
//        this.graphics.beginFill(col);
//        this.graphics.drawCircle(0,0,5);
//        this.graphics.endFill();
    }
    
}

class handleTouchPoint extends touchPoint {
    public var ptList:Array = new Array();
    private var ox:Number, oy:Number;
    public var drawLayer:Sprite = new Sprite();
    public function handleTouchPoint() {
    }
    //ドラッグ開始
    protected override function downHandler(e:MouseEvent):void
    {
        ox = drawLayer.mouseX;
        oy = drawLayer.mouseY;
        drawLayer.graphics.clear();
        drawLayer.graphics.moveTo(ox, oy);
        this.startDrag();
        this.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }
    //ドラッグ終了
    protected override function upHandler(e:MouseEvent):void {
        this.stopDrag();
        this.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }
    private function handleEnterFrame(event:Event):void {
        var nx:Number = drawLayer.mouseX;
        var ny:Number = drawLayer.mouseY;
        drawLayer.graphics.lineStyle(1,0xFFFFFF);
        //drawLayer.graphics.moveTo(nx, ny);
        drawLayer.graphics.moveTo(halfNum(nx,ox), halfNum(ny,oy));
        this.graphics.curveTo( nx, ny,halfNum(nx,ox), halfNum(ny,oy) );
        //drawLayer.graphics.lineTo(ox, oy);
        ox = nx;
        oy = ny;
    }
    private function halfNum(a:Number, b:Number):Number {
        return a+(b-a)/2;
    }
    
}