SVGでへのへのもへじ

by y_tti
♥0 | Line 236 | Modified 2010-06-29 00:16:53 | MIT License
play

ActionScript3 source code

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

package
{
    import gs.TweenMax;
    import gs.easing.Elastic;
    
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.system.Security;
    import flash.system.SecurityDomain;
    
    import frocessing.core.F5Graphics;
    import frocessing.shape.FShape;
    import frocessing.shape.FShapeContainer;
    import frocessing.shape.FShapeLine;
    import frocessing.shape.FShapeRect;
    import frocessing.shape.FShapeSVG;
    import frocessing.shape.IFShape;

    [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "0xFFFFFF")]
    public class SVGTest extends Sprite
    {
        private var _loader:URLLoader;
        private var _shapedata:FShapeSVG;
        private var _commands:Vector.<int>;
        private var _vertices:Vector.<Particle>;
        private var _canvas:Sprite;
        private var _fshapes:Array;
        
        public static const MOVE_TO    :int = 1;
        public static const LINE_TO    :int = 2;
        public static const CURVE_TO   :int = 3;
        public static const BEZIER_TO  :int = 10;
        public static const CLOSE_PATH :int = 100;
        
        
        public function SVGTest()
        {
            Wonderfl.capture_delay( 5 );
            addEventListener(Event.ADDED_TO_STAGE , _init );
        }
        
        private function _init(e:Event):void {
            var svgURL:String = "http://www.y-tti.com/lab/assets/henoheno.svg";
            
            //お借りします。ありがとうございます。
            //http://5ivestar.org/blog/2008/12/wonderfl-webproxy/
            Security.loadPolicyFile("http://5ivestar.org/proxy/crossdomain.xml");
            _loader = new URLLoader();
            _loader.addEventListener(Event.COMPLETE , _loaderHandler);
            _loader.load(new URLRequest("http://5ivestar.org/proxy/"+svgURL));
        }

        private function _loaderHandler(event:Event):void
        {
            //SVGパース
            var svg:XML = XML(_loader.data);
            _shapedata = new FShapeSVG(svg);
            
            //真ん中寄せ
            var shapeSP:Sprite = _shapedata.toSprite();
            _canvas = new Sprite();
            addChild(_canvas);
            _canvas.x = (stage.stageWidth - shapeSP.width)>>1;
            _canvas.y = (stage.stageHeight - shapeSP.height)>>1;
            
            _commands = new Vector.<int>();
            _vertices = new Vector.<Particle>();
            
            _fshapes = [];
            _getFshapes(_shapedata);    //FShape型やその他の型を取り出す
            _parse();    //MOVE_TOやその他のアクションと位置を保持
            
            addEventListener(Event.ENTER_FRAME , _update);
            _canvas.addEventListener(MouseEvent.ROLL_OVER , _rollOverHandler);
        }

        private function _getFshapes($fshapeContainer:FShapeContainer):void {
            //中身がFShapeContainerだったときは再帰
            for (var i:int = 0; i < $fshapeContainer.getChildCount(); i++) {
                var shape:IFShape = $fshapeContainer.getChildAt(i);
                if(shape is FShapeContainer) {
                    arguments.callee(shape);
                } else {
                    _fshapes.push(shape);
                }
            }
        }
        
        private function _parse():void {
            //_commandsに命令
            //_verticesに位置をぶちこむ
            for (var i:int = 0; i < _fshapes.length; i++) {
                var shape:IFShape =_fshapes[i];
                if(shape is FShapeLine){
                    var fline:FShapeLine = FShapeLine(shape);
                    _commands.push(MOVE_TO);
                    _vertices.push( new Particle(fline.x1,fline.y1)  );
                    _commands.push(LINE_TO);
                    _vertices.push( new Particle(fline.x2,fline.y2)  );
                } else if(shape is FShape) {
                    var fshape:FShape = FShape(shape);
                    var xi:int = 0;
                    var yi:int = 1;
                    for (var j:int = 0; j < fshape.commands.length; j++) {
                        var cmd:int = fshape.commands[j];
                        if ( cmd == LINE_TO )
                        {
                            _commands.push(LINE_TO);
                            _vertices.push(  new Particle(fshape.vertices[xi],fshape.vertices[yi])  );
                            xi += 2;
                            yi += 2;
                        }
                        else if ( cmd == BEZIER_TO )
                        {
                            _commands.push(BEZIER_TO);
                            _vertices.push(  
                                new Particle(fshape.vertices[xi],fshape.vertices[yi]) ,
                                new Particle(fshape.vertices[xi+2],fshape.vertices[yi+2]),
                                new Particle(fshape.vertices[xi+4],fshape.vertices[yi+4]));
                            xi += 6;
                            yi += 6;
                        }
                        else if ( cmd == CURVE_TO )
                        {
                            _commands.push(CURVE_TO);
                            _vertices.push( new Particle(fshape.vertices[xi],fshape.vertices[yi]),
                                            new Particle(fshape.vertices[xi+2],fshape.vertices[yi+2]));
                            xi += 4;
                            yi += 4;
                        }
                        else if ( cmd == MOVE_TO )
                        {
                            _commands.push(MOVE_TO);
                            _vertices.push( new Particle(fshape.vertices[xi],fshape.vertices[yi]) );
                            xi += 2;
                            yi += 2;
                        }
                        else if ( cmd == CLOSE_PATH )
                        {
                            _commands.push(CLOSE_PATH);
                        }
                    }
                } else if(shape is FShapeRect){
                    var frect:FShapeRect = FShapeRect(shape);
                    _commands.push(MOVE_TO);
                    _vertices.push( new Particle(frect.x,frect.y)  );
                    _commands.push(LINE_TO);
                    _vertices.push( new Particle(frect.x +frect.width,frect.y)  );
                    _commands.push(LINE_TO);
                    _vertices.push( new Particle(frect.x +frect.width,frect.y+frect.height)  );
                    _commands.push(LINE_TO);
                    _vertices.push( new Particle(frect.x,frect.y+frect.height)  );
                    _commands.push(CLOSE_PATH);
                }
            }
        }
        
        //private var _t:TimelineMax;
        private var _isOverMotion:Boolean = false;
        private function _rollOverHandler(event:MouseEvent):void
        {
            //ロールオーバーでデフォルト位置へ戻してる。
            //if(_t && _t.active) return;
            if(_isOverMotion) return;
            //_t = new TimelineMax();
            for (var i:int = 0; i < _vertices.length; i++) {
                var p:Particle = _vertices[i] as Particle;
            //    _t.insert(
                    TweenMax.to(p ,1 , {x:p.initX , y:p.initY , ease:Elastic.easeOut,easeParams:[5,1],delay:i*0.02,onComplete:function():void{_isOverMotion=false;}} );
            //    );
            }
        }
        
        private function _update(e:Event):void {
            //位置を更新してドロー
            //if(  !(_t && _t.active)  ){
            if(!_isOverMotion){
                for (var i:int = 0; i < _vertices.length; i++) {
                    var p:Particle = _vertices[i] as Particle;
                    p.x += Math.random()*6-3;
                    p.y += Math.random()*6-3;
                }
            }
            _draw();
        }
        private function _draw():void {
            //線を書く
            var sx:Number = 0;
            var sy:Number = 0;
            var px:Number = 0;
            var py:Number = 0;
            var xi:int    = 0;
            var yi:int    = 1;
            var pi:int    = 0;
            
            var gc:Graphics = _canvas.graphics;
            gc.clear();
            gc.lineStyle(2,0x0,1);
            for (var i:int = 0; i < _commands.length; i++) {
                var cmd:int = _commands[i];
                if ( cmd == LINE_TO )
                {
                    px = _vertices[pi].x;
                    py = _vertices[pi].y;
                    gc.lineTo( px, py );
                    pi += 1;
                }
                else if ( cmd == BEZIER_TO )
                {
                    var bx:Number = _vertices[uint(pi+2)].x;
                    var by:Number = _vertices[uint(pi+2)].y;
                    _draw_bezier( gc, px, py, _vertices[pi].x, _vertices[pi].y, _vertices[uint(pi+1)].x, _vertices[uint(pi+1)].y, bx, by );
                    px = bx;
                    py = by;
                    pi += 3;
                }
                else if ( cmd == CURVE_TO )
                {
                    px = _vertices[uint(pi+1)].x;
                    py = _vertices[uint(pi+1)].y;
                    gc.curveTo( _vertices[xi].x, _vertices[yi].y, px, py );
                    pi += 2;
                }
                else if ( cmd == MOVE_TO )
                {
                    sx = px = _vertices[pi].x;
                    sy = py = _vertices[pi].y;
                    gc.moveTo( sx, sy );
                    pi += 1;
                }
                else if ( cmd == CLOSE_PATH )
                {
                    gc.lineTo( sx, sy );
                    px = sx;
                    py = sy;
                }
            }    
        }
        
        public var bezierDetail:uint = 20;
        
        private function _draw_bezier( gc:Graphics, x0:Number, y0:Number, cx0:Number, cy0:Number, cx1:Number, cy1:Number, x:Number, y:Number ):void
        {
            var k:Number = 1.0/bezierDetail;
            var t:Number = 0;
            var tp:Number;
            for ( var i:int = 1; i <= bezierDetail; i++ )
            {
                t += k;
                tp = 1.0-t;
                gc.lineTo( x0*tp*tp*tp + 3*cx0*t*tp*tp + 3*cx1*t*t*tp + x*t*t*t, 
                    y0*tp*tp*tp + 3*cy0*t*tp*tp + 3*cy1*t*t*tp + y*t*t*t );
            }
        }
    }
}
import flash.geom.Point;

class Particle{
    public var x:Number = 0;
    public var y:Number = 0;
    public var initX:Number = 0;
    public var initY:Number = 0;
    public function Particle($x:Number=0,$y:Number=0){
        x = initX = $x;
        y = initY = $y;
    }
}