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

VectorImage用ツール いろいろ

ベクタ画像の大きさを変更できるようにした。
z:ズームイン
x:ズームアウト
a:視点移動
c:視点リセット
クリック&ドラッグ: 画像選択,画像変形
delete: 選択画像消去
Get Adobe Flash player
by shohei909 24 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/kQEf
 */

// forked from shohei909's VectorImageUtil
// forked from shohei909's VectorImage class
//ベクタ画像の大きさを変更できるようにした。


//z:ズームイン
//x:ズームアウト
//a:視点移動
//c:視点リセット
//クリック&ドラッグ: 画像選択,画像変形
//delete: 選択画像消去

package{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    
    [SWF(backgroundColor="#333333", frameRate="60", width="465", height="465")]
    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 FIELD_RECT:Rectangle = new Rectangle(10,10,445,400);
        private var field:SlideSprite;
        public function VectorTest():void{
            var canvas:Canvas = new Canvas(100,100);
            var workSpace:WorkSpace = new WorkSpace(canvas); 
            var segment:Vector.<Array> = VectorImageUtil.segmentation(IMG_PASS)
            
            canvas.addChildren( segment );
           
            field = new SlideSprite(FIELD_RECT);
            field.addChild( canvas ); field.addChild( workSpace );
            addChild(field);
            
            var frame:Bitmap = new Bitmap(new BitmapData(465,465,true,0xFF000000));
            frame.bitmapData.fillRect(FIELD_RECT,0x00000000);
            addChild(frame);
            
            stage.addEventListener("keyDown",onKeyDown);
        }
        public function onKeyDown(e:KeyboardEvent):void{
            var c:DynamicSprite = field.container;
            if(e.keyCode == 88){ c.zoom(c.mouseX,c.mouseY,c.scaleX/2);
            }else if(e.keyCode == 90){ c.zoom(c.mouseX,c.mouseY,c.scaleX*2);
            }else if(e.keyCode == 65){ c.zoom(c.mouseX,c.mouseY,c.scaleX);
            }else if(e.keyCode == 67){ c.reset(); }
        }
    }
}
import flash.events.KeyboardEvent;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.BlendMode;
import flash.events.Event;
import flash.geom.Rectangle;


//拡大、縮小、スライドが滑らかにできるSprite===============================================================
class DynamicSprite extends Sprite{
    public var rect:Rectangle; public var rate:Number = 1; public var focusX:Number = 0; public var focusY:Number = 0;
    protected  var speed:Number = 7;
    public static const MAX_RATE:Number = 64; public static const MIN_RATE:Number = 1/16;
    public static const ON_ZOOM:String = "zoom";
    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.height/2,1,3);   }
    //焦点の移動
    protected function focus(e:Event):void{
        if( Math.abs(x-focusX)>0.1 || Math.abs(y-focusY)>0.1 || Math.abs(rate-scaleY)>0.00001 || Math.abs(rate-scaleX)>0.00001){
            scaleX = ( scaleX*speed + rate) / (speed+1);scaleY = ( scaleY*speed + rate) / (speed+1);
            x = ( x*speed + focusX) / (speed+1); y=( y*speed + focusY) / (speed+1);
            dispatchEvent(new Event("zoom"));
        }
    } 
}


//=====================================================================================================
class SlideSprite extends Sprite{
    private static const BAR_WIDTH:Number = 15;
    private static const BAR_COLOR:Number = 0x222222;
    private static const BACK_COLOR:Number = 0x111111;
    private static const BAR_PASS:Array = [[[1,0.0,0x440000,0.0,0x441111,1.0],[0,0,0],[0,1,0],[1,1,0],[1,0,0]]];
    public var container:DynamicSprite;
    public var maskSprite:Sprite = new Sprite();
    public function SlideSprite(r:Rectangle){
        x=r.x; y=r.y;
        graphics.beginFill(BAR_COLOR,1.0); graphics.drawRect(0,0,r.width,r.height);
        graphics.beginFill(BACK_COLOR,1.0); graphics.drawRect(0,0,r.width-BAR_WIDTH,r.height-BAR_WIDTH);
        maskSprite.graphics.beginFill(0x000000,1.0); maskSprite.graphics.drawRect(0,0,r.width-BAR_WIDTH,r.height-BAR_WIDTH);
        container = new DynamicSprite( new Rectangle(0,0,r.width-BAR_WIDTH,r.height-BAR_WIDTH) );
        container.mask = maskSprite;
        super.addChild(container); super.addChild(maskSprite);
        container.addEventListener("zoom",setBar);
        setBar();
    }
    override public function addChild(spr:DisplayObject):DisplayObject{
        return container.addChild(spr);
    }
    private function setBar(e:Event=null):void{
        var outR:Rectangle = maskSprite.getRect(this);
        var inR:Rectangle =outR.union(container.getRect(this));
    }
}


//ベクタ画像を配置するスプライト===========================================================================================
class Canvas extends Sprite{
     public var vectorChildren:Vector.<VectorImage>=new Vector.<VectorImage>();
     private static const BACK_PASS:Array = [[[1,0.5,0xDDDDDD,1.0,0xFFFFFF,1.0],[0,0,0],[0,1,0],[1,1,0],[1,0,0]]];
     public function Canvas(w:int,h:int){
        addChild(  new VectorImage(VectorImageUtil.transform( BACK_PASS, new Matrix(w,0,0,h),new Point))  );
    }
     private 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]);
    }
    //ベクタ画像をリストから削除
    public function removeChildren(imgs:Vector.<VectorImage>):void{
        for each(var img:VectorImage in imgs) {
            removeChild(img); vectorChildren.splice(vectorChildren.indexOf(img),1)
        }
    }
}
//=====================================================================================================



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,3,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 canvas: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;
    private var power:Boolean=false;
    public function WorkSpace(canvas:Canvas):void{
        this.canvas=canvas; addEventListener(Event.ADDED_TO_STAGE,init);
    }
    public function init(e:Event=null):void{
        removeEventListener(Event.ADDED_TO_STAGE,init);
        moving={move:false,n:0,i:0,j:0,x:0,y:0}; selecting={x:0,y:0};
        marks=[];
        frame = new VectorImage(FRAME_PASS); selection = new VectorImage(SELECT_PASS);
        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]); 
                }
            }
        }
        on();
    }
    
    //このワークスペースを機能させる
    public function on():void{
        if(power==false){
            visible=true;
            stage.addEventListener("mouseDown",onMouseDown);
            addEventListener("enterFrame",onFrame);
            stage.addEventListener("mouseUp",onMouseUp);
            stage.addEventListener("keyDown",onKeyDown);
            reset();
        }
    }
    
    //このワークスペースの機能を停止する
    public  function off():void{
        if(power==false){
            visible=false;
            stage.removeEventListener("mouseDown",onMouseDown);
            removeEventListener("enterFrame",onFrame);
            stage.removeEventListener("mouseUp",onMouseUp);
            stage.removeEventListener("keyDown",onKeyDown);
        }
    }

    //選択している画像をリセット
    private function reset():void{  selected = new Vector.<VectorImage>(); update(); }
    //画像を選択
    private function select(imgs:Vector.<VectorImage>):void{  selected=imgs; update(); }
    //画像を消去
    private function del():void{ canvas.removeChildren(selected);reset(); }
    
    //選択している画像を更新
    private function update():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 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:Number=mouseX-moving.x;  var moveY:Number=mouseY-moving.y;
                if(Math.abs(moveX)>0 || Math.abs(moveY)>0 ){
                    var i:Number=moving.i; var j:Number=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:Number=p2.x-p1.x; var h:Number=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));
                    }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))); }
                    }
                    update();
                }
            }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(canvas);
            selection.visible=false;
            select(VectorImageUtil.select(canvas.vectorChildren,r));
        }
        mouseDown=false; moving.move=false;
    }
    //キー操作
    public function onKeyDown(e:KeyboardEvent):void{
      if(e.keyCode==46){del();}
    }
}
//====================================================================================================


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]);
    }
}
//=========================================================================================================================================================================================