In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

VectorImageUtil

ベクタ画像の大きさを変更できるようにした。
z:ズームイン
x:ズームアウト
a:視点移動
c:視点リセット
クリック&ドラッグ: 画像選択,画像変形
Get Adobe Flash player
by shohei909 04 Jul 2010
/**
 * Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rUJh
 */

// forked from shohei909's VectorImage class
package{
    //ベクタ画像の大きさを変更できるようにした。
    
    //z:ズームイン
    //x:ズームアウト
    //a:視点移動
    //c:視点リセット
    //クリック&ドラッグ: 画像選択,画像変形
    
    
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    
    public class VectorTest extends Sprite{
        private static const IMG_PASS:Array = [[[1,1.5,0x000000,1.0,0x00FF22,1.0],[12,6,1],[38,6,1],[50,35,1],[40,35,1],[40,50,1],[25,40,1],[10,50,1],[10,35,1],[0,35,1]],[[1,1.5,0x000000,1.0,0xFF0000,1.0],[36,14,0],[14,14,0],[14,22,0],[36,22,0]],[[1,1.5,0x000000,1.0,0xFF0000,1.0],[6,10,0],[22,10,0]],[[1,1.5,0x000000,1.0,0xFF0000,1.0],[42,10,0],[28,10,0]]];
        private static const BACK_PASS:Array = [[[1,1.5,0xAAAAAA,1.0,0xFFFF22,0.2],[0,0,0],[0,420,0],[420,420,0],[420,0,0]],[[0,1.5,0xAAAAAA,1.0,0x00FF22,0.0],[190,210,0],[230,210,0]],[[0,1.5,0xAAAAAA,1.0,0x00FF22,0.0],[210,190,0],[210,230,0]]];
        private static const FIELD_RECT:Rectangle = new Rectangle(10,10,420,420);
        private var field:DynamicSprite;
        public function VectorTest():void{
            var canvas:Canvas = new Canvas();
            var workSpace:WorkSpace = new WorkSpace(canvas); 
            
            var segment:Vector.<Array> = VectorImageUtil.segmentation(IMG_PASS)
            canvas.addChildren( segment );
           
            field = new DynamicSprite(FIELD_RECT);
            field.addChild( new VectorImage(BACK_PASS) );
            field.addChild( canvas );           
            field.addChild( workSpace );
            addChild(field);
            
            workSpace.select( canvas.vectorChildren );
            stage.addEventListener("keyDown",onKeyDown);
        }
        public function onKeyDown(e:KeyboardEvent):void{
            if(e.keyCode == 88){
                field.zoom(field.mouseX,field.mouseY,field.scaleX/2);
            }else if(e.keyCode == 90){
                field.zoom(field.mouseX,field.mouseY,field.scaleX*2);
            }else if(e.keyCode == 65){
                field.zoom(field.mouseX,field.mouseY,field.scaleX);
            }else if(e.keyCode == 67){
                field.reset();
            }
        }
    }
}


import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;

//拡大、縮小、スライドが滑らかにできるSprite===============================================================
class DynamicSprite extends Sprite{
    public var rect:Rectangle;
    private var rate:Number = 1;
    private var speed:Number = 7;
    private var focusX:Number = 0;
    private var focusY:Number = 0;
    private static const MAX_RATE:Number = 64;
    private static const MIN_RATE:Number = 1/16;
    public function DynamicSprite(r:Rectangle){
        rect = r;
        x=rect.x;y=rect.y;
        focusX=x;
        focusY=y;
        addEventListener("enterFrame",focus);
    }

    //ズーム
    public function zoom(fx:Number,fy:Number,r:Number,s:int = 7):void{
        if(r>MAX_RATE){r=MAX_RATE;}
        if(r<MIN_RATE){r=MIN_RATE;}
        speed=s;
        rate=r;
        focusX=-fx*rate+rect.x+rect.width/2;
        focusY=-fy*rate+rect.y+rect.height/2;
    }

    //ズームのリセット
    public function reset():void{
        zoom(rect.width/2,rect.width/2,1,3);
    }
    
    //焦点の移動
    private function focus(e:Event):void{
        scaleX = ( scaleX*speed + rate) / (speed+1);
        scaleY = ( scaleY*speed + rate) / (speed+1);
        x = ( x*speed + focusX) / (speed+1);
        y = ( y*speed + focusY) / (speed+1);
    } 
}
//=====================================================================================================



//ベクタ画像を配置するスプライト===========================================================================================
class Canvas extends Sprite{
    public var vectorChildren:Vector.<VectorImage>=new Vector.<VectorImage>();
    public function add(pass:Array):void{
        var img:VectorImage = new VectorImage(pass);
        vectorChildren.push(img);
        addChild(img);
    }
    public function addChildren(pass:Vector.<Array>):void{
        var l:int = pass.length;
        for(var i:int=0;i<l;i++){
            add(pass[i]);
        }
    }
}
//=====================================================================================================


import flash.events.MouseEvent;
//変形用の枠などを表示する場所============================================================================
class WorkSpace extends Sprite{
    private static const MARK_PASS:Array = [[[1,0.5,0xDD0000,1.0,0xFF6666,0.8],[-3,3,0],[-3,-3,0],[3,-3,0],[3,3,0]]];
    private static const FRAME_PASS:Array = [[[0,6,0x666666,0.8,0xFF0000,0],[0,0,0],[1,0,0],[1,1,0],[0,1,0],[0,0,0]]];
    private static const SELECT_PASS:Array = [[[1,0.5,0x0000FF,0.5,0x0000FF,0.2],[0,0,0],[1,0,0],[1,1,0],[0,1,0]]];
    public var targetCanvas:Canvas;
    public var selected:Vector.<VectorImage>;
    
    private var marks:Array;
    private var frame:VectorImage;
    private var selection:VectorImage;
    private var moving:Object;
    private var selecting:Object;
    private var mouseDown:Boolean;
    public function WorkSpace(canvas:Canvas):void{
        targetCanvas=canvas;
        addEventListener(Event.ADDED_TO_STAGE,init);
    }
    public function init(e:Event=null):void{
        removeEventListener(Event.ADDED_TO_STAGE,init);
        stage.addEventListener("mouseDown",onMouseDown);
        addEventListener("enterFrame",onFrame);
        stage.addEventListener("mouseUp",onMouseUp);
        moving={move:false,n:0,i:0,j:0,x:0,y:0};
        selecting={x:0,y:0};
        frame = new VectorImage(FRAME_PASS);
        selection = new VectorImage(SELECT_PASS);
        marks=[];
        addChild(frame);
        addChild(selection);
        selection.visible=false;
        for(var i:int=0;i<3;i++){
            marks[i]=[];
            for(var j:int=0;j<3;j++){
                if(i==1 && j==1){ marks[i][j]=false;}
                else{
                    marks[i][j]=new VectorImage(MARK_PASS);
                    addChild(marks[i][j]); 
                }
            }
        }
        reset();
    }
    public function reset():void{
        selected = new Vector.<VectorImage>();
        move();
    }
     
    public function move():void{
        var l:int = selected.length;
        if(l>0){
            var r:Rectangle = selected[0].getRect(this);
            r.width++;r.height++;
            for(var n:int=1;n<l;n++){
                var r2:Rectangle = selected[n].getRect(this);
                r2.width++;r2.height++;
                r=r.union(r2);
            }
            frame.visible = true;
            frame.read(VectorImageUtil.transForm( FRAME_PASS,new Matrix(r.width,0,0,r.height,r.x,r.y),new Point(0,0) ));
            for(var i:int=0;i<3;i++){
                for(var j:int=0;j<3;j++){
                    if(i!=1 || j!=1){
                        marks[i][j].visible=true;
                        marks[i][j].x=r.x+r.width*i/2;
                        marks[i][j].y=r.y+r.height*j/2;
                    }
                }
            }
        }else{
            frame.visible = false;
            for(i=0;i<3;i++){
                for(j=0;j<3;j++){
                    if(i!=1 || j!=1){ marks[i][j].visible=false; }
                }
            }
        }
    }
    
    public function select(imgs:Vector.<VectorImage>):void{
        selected = imgs;
        move(); 
    }
    
    public function onMouseDown(e:MouseEvent):void{
        var l:int=selected.length;
        mouseDown = true;
        if(l>0){
            if(frame.hitTestPoint(e.stageX,e.stageY,false)){
                moving.move=true;
                moving.i=1; moving.j=1;
                moving.x=mouseX; moving.y=mouseY;
            }
            for(var i:int=0;i<3;i++){
                for(var j:int=0;j<3;j++){
                    if( (i!=1 || j!=1) && marks[i][j].hitTestPoint(e.stageX,e.stageY) ){
                        moving.move=true;
                        moving.i=i;  moving.j=j;
                        moving.x=mouseX;  moving.y=mouseY;
                    }
                }
            }
        }
        if(moving.move!=true){
            reset();
            selection.visible=true;
            selecting.x=mouseX; selecting.y=mouseY;
        }
    }
    
    public function onFrame(e:Event):void{
        if(mouseDown){
            if(moving.move){
                var moveX:int = mouseX-moving.x;  var moveY:int = mouseY-moving.y;
                if(Math.abs(moveX)>0 || Math.abs(moveY)>0 ){
                    var i:int = moving.i; var j:int = moving.j;
                    moving.x=mouseX; moving.y=mouseY;
                    if(i!=1||j!=1){
                        var p1:Point = new Point(marks[0][0].x,marks[0][0].y);  var p2:Point = new Point(marks[2][2].x,marks[2][2].y);
                        var np1:Point = new Point(marks[0][0].x,marks[0][0].y);  var np2:Point = new Point(marks[2][2].x,marks[2][2].y);
                        if(moving.i==0){ np1.x+=moveX; }   if(moving.i==2){ np2.x+=moveX; }
                        if(moving.j==0){ np1.y+=moveY; }   if(moving.j==2){ np2.y+=moveY; }
                        
                        var m:Matrix = new Matrix();
                        var w:int=p2.x-p1.x;var h:int=p2.y-p1.y;
                        if(w==0){w=np2.x-np1.x}  if(h==0){h=np2.y-np1.y}
                        if(np2.x-np1.x!=0 && np2.y-np1.y!=0){m.scale( (np2.x-np1.x)/w, (np2.y-np1.y)/h);}
                        if(np2.x-np1.x<0){moving.i=2-moving.i;}   if(np2.y-np1.y<0){moving.j=2-moving.j;}
                        
                        var p:Point = new Point(marks[2-i][2-j].x,marks[2-i][2-j].y);
                        var l:int = selected.length;
                        for(var n:int=0;n<l;n++){
                            selected[n].read(VectorImageUtil.transForm(selected[n].data,m,p));
                        }
                        move();
                    }else{
                        l = selected.length;
                        for(n=0;n<l;n++){  selected[n].read(VectorImageUtil.transForm(selected[n].data, new Matrix(1,0,0,1,moveX,moveY), new Point(0,0))); }
                        move();
                    }
                }
            }else{
                var r:Rectangle = new Rectangle(selecting.x,selecting.y);
                r.right=mouseX; r.bottom=mouseY;
                selection.read(VectorImageUtil.transForm( SELECT_PASS,new Matrix( r.width,0,0,r.height,r.x,r.y),new Point(0,0) ));
            }
        }
    }
    public function onMouseUp(e:MouseEvent):void{
        if(moving.move==false){
            var r:Rectangle = selection.getRect(targetCanvas);
            selection.visible=false;
            select(VectorImageUtil.select(targetCanvas.vectorChildren,r));
        }
        mouseDown=false;
        moving.move=false;
    }
}
//====================================================================================================






import flash.geom.Matrix;
import flash.geom.Point;

//ベクタ画像用のユーティリティ==========================================================================================
class VectorImageUtil{
    //画像のdotsをマトリックスで変換したものを返します。
    //pointは変換の原点
    public static function transForm(pass1:Array,m:Matrix,point:Point):Array{
        var pass2:Array = [];
        var size:int = pass1.length;
        for(var i:int=0;i<size;i++){
            pass2[i]=[];pass2[i][0]=[];
            for(var n:int=0;n<6;n++){pass2[i][0][n]=pass1[i][0][n];}
            var l:int = pass1[i].length;
            for(var j:int=1;j<l;j++){
                pass2[i][j]=[];
                var p:Point = new Point(pass1[i][j][0]-point.x,pass1[i][j][1]-point.y);
                p = m.transformPoint(p);
                pass2[i][j][0] = p.x+point.x;
                pass2[i][j][1] = p.y+point.y;
                pass2[i][j][2] = pass1[i][j][2];
            }
         }
        return pass2;
    }
    
    //一つのベクタ画像のパスを複数に分解します
    public static function segmentation(pass:Array):Vector.<Array>{
        var segments:Vector.<Array>=new Vector.<Array>([]);
        var size:int = pass.length;
        for(var n:int=0;n<size;n++){
           segments[n]=[];segments[n][0]=[];
           var l:int = pass[n].length;
           for(var m:int=0;m<l;m++){
               segments[n][0][m]=[];
               var l2:int = pass[n][m].length;
               for(var k:int = 0;k<l2;k++){segments[n][0][m][k]=pass[n][m][k];}
           }
        }
        return segments;
    }
    
    //一つのベクタ画像の頂点が長方形内に含まれるかをテストします。
    public static function hitTestRect(pass:Array,rect:Rectangle):Boolean{
        var size:int = pass.length;
        for(var n:int=0;n<size;n++){
           var l:int = pass[n].length;
           for(var m:int=1;m<l;m++){
               var l2:int = pass[n][m].length;
               if(rect.contains(pass[n][m][0],pass[n][m][1])){return true;}
           }
        }
        return false;
    }
    //長方形内に含まれるベクタ画像を選び出します。
    public static function select(imgs:Vector.<VectorImage>,rect:Rectangle):Vector.<VectorImage>{
        var selection:Vector.<VectorImage> = new Vector.<VectorImage>();
        var size:int = imgs.length;
        for(var n:int=0;n<size;n++){
           if(hitTestRect(imgs[n].data,rect)){selection.push(imgs[n]);}
        }
        return selection;
    }
    
    
    //二つの画像の中間の画像を返します。
    //time 0:モーフィング開始  1:モーフィング終了
    public static function morphing(pass1:Array,pass2:Array,time:Number):Array{
        if( morphable(pass1,pass2) ==false){return pass2;}
        var neutral:Array = [];
        var size:int = pass1.length;
        var time2:Number = 1-time;
        for(var i:int=0;i<size;i++){
            neutral[i]=[];neutral[i][0]=[];
            neutral[i][0][0] = pass1[i][0][0];
            neutral[i][0][1] = pass1[i][0][1]*time2 + pass2[i][0][1]*time;
            neutral[i][0][2] = colorMorphing(pass1[i][0][2],pass2[i][0][2],time);
            neutral[i][0][3] = pass1[i][0][3]*time2 + pass2[i][0][3]*time;
            neutral[i][0][4] = colorMorphing(pass1[i][0][4],pass2[i][0][4],time);
            neutral[i][0][5] = pass1[i][0][5]*time2 + pass2[i][0][5]*time;
            var l:int = pass1[i].length;
            for(var j:int=1;j<l;j++){
                neutral[i][j]=[];
                for(var k:int=0;k<3;k++){neutral[i][j][k] = pass1[i][j][k]*time2 + pass2[i][j][k]*time;}
            }
         }
        return neutral;
    }
    
    //二つの画像がモーフィング可能かを返します。
    public static function morphable(pass1:Array,pass2:Array):Boolean{
        var size:int = pass1.length;
        if(size != pass2.length){return false;}
        for(var i:int=0;i<size;i++){
            if(pass1[i][0][0]!=pass2[i][0][0] || pass1[i].length!=pass2[i].length){return false;}
        }
        return true;
    }
    
    //二つの色の中間色を返します。
    public static function colorMorphing(color1:uint,color2:uint,time:Number):uint{
        return color1;
    }
}
//=====================================================================================================

import flash.display.Shape;

//ベクタ画像用クラス=================================================================================================================================================================
class VectorImage extends Shape{
    public var data:Array;
    public var styles:Vector.<Array>;        //styles[][],,,style:[open/close,lineWeight,lineColor,lineAlpha,fillColor,fillAlpha]
    public var dots:Vector.<Array>;            //dots[][][],,,dot:[x,y,curve]
    
    //コンストラクタ
    public function VectorImage(pass:Array){ read(pass); }

    //データの読み込み
    public function read(pass:Array):void{
        data = pass;
        styles = new Vector.<Array>();
        dots = new Vector.<Array>();
        var size:int = pass.length
        for(var i:int=0;i<size;i++){
            styles[i] = [];dots[i] = [];
            for(var j:int=0;j<6;j++){ styles[i][j]=pass[i][0][j]; }
            var l:int =pass[i].length-1;
            for(var k:int=0;k<l;k++){
                dots[i][k] = [];
                for(var n:int=0;n<3;n++){ dots[i][k][n]=pass[i][k+1][n]; }
            }
        }
        drow();
    }

    //データの描画
    public function drow():void{
        var size:int = styles.length;
        graphics.clear();
        for(var i:int=0;i<size;i++){
            var l:int=dots[i].length;
            graphics.lineStyle(styles[i][1],styles[i][2],styles[i][3]);
            if(styles[i][0]==1){ graphics.beginFill(styles[i][4],styles[i][5]); var bf:Array=dots[i][l-1];}
            else{ bf=dots[i][0];}
            graphics.moveTo( center(bf,dots[i][0],0),center(bf,dots[i][0],1) ); 
            for(var j:int=0;j<l-1;j++){  line(bf,dots[i][j],dots[i][j+1]);bf=dots[i][j]; }
            if(styles[i][0]==1){ line( bf, dots[i][j], dots[i][0]);  }
            else{  line(bf, dots[i][j], dots[i][j] ); }
        }
    }
    private function line(dot1:Array,dot2:Array,dot3:Array):void{
        graphics.lineTo( center(dot2,dot1,0),center(dot2,dot1,1) );
        if(dot2[2]>0){graphics.curveTo( dot2[0],dot2[1],center(dot2,dot3,0),center(dot2,dot3,1) );}
    }
    private function center(dot1:Array,dot2:Array,xy:int):Number{
        if( dot1[2] == 0){return dot1[xy];}
        return (dot1[xy]*dot2[2]+dot2[xy]*dot1[2]*dot1[2])/(dot1[2]*dot1[2]+dot2[2]);
    }
}
//=========================================================================================================================================================================================