2012/06/29

TWaver Has Realized Elements’ Dynamic Rotation

Recently a client has made a requirement on the dynamic rotation of elements. It is quite convenient to satisfy it with TWaver.
Main functions that have been realized:
  1. The dynamic rotation of elements;
  2. The effect of the element which is selected: the selected element will move quickly to the front and then stop rotating. It will start to rotate again automatically once it is not selected;
  3. Able to adjust the direction of the rotation by itself according to the position of the mouse;
  4. Able to change fw/bw/fh/bh in the program to adjust the presentation of the images.
The effect is presented in the folimage image:
The code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                layout="absolute"
                creationComplete="test()"
                width="100%"
                height="100%"
                xmlns:ns="http://www.servasoftware.com/2009/twaver/flex">
    <mx:Script>
        <![CDATA[
            import mx.events.ResizeEvent;

            import twaver.Collection;
            import twaver.Consts;
            import twaver.ElementBox;
            import twaver.IData;
            import twaver.IElement;
            import twaver.Layer;
            import twaver.Node;
            import twaver.SelectionChangeEvent;
            import twaver.SelectionModel;
            import twaver.Styles;
            import twaver.SubNetwork;
            import twaver.Utils;
            import twaver.core.util.l.u;
            private var box:ElementBox = new ElementBox();

            private var _rotationList:Collection = new Collection();
            private var rectIndexMap:Object = {};
            private var indexRectMap:Object = {};
            private var rList:Collection = new Collection();
            private var _startAngle:Number = 90;
            private var timer:Timer;
            private var _selectNode:Node;

            private var _clockSise:Boolean = false;

            private var _stopAngle:Number = 0;
            private var _needStop:Boolean = false;

            [Embed(source="images/1.png")]
            public static const p1:Class;
            [Embed(source="images/2.png")]
            public static const p2:Class;
            [Embed(source="images/3.png")]
            public static const p3:Class;
            [Embed(source="images/4.png")]
            public static const p4:Class;
            [Embed(source="images/5.png")]
            public static const p5:Class;
            [Embed(source="images/6.png")]
            public static const p6:Class;
            [Embed(source="images/7.png")]
            public static const p7:Class;
            [Embed(source="images/8.png")]
            public static const p8:Class;

            public function get clockSise():Boolean
            {
                return _clockSise;
            }

            public function set clockSise(value:Boolean):void
            {
                if(this.clockSise==value){
                    return;
                }
                _clockSise = value;
            }
            private function resetClockSize( point:Point):void {
                if (_needStop == true) {
                    return;
                }
                if (point.x > this.network.width / 2) {
                    clockSise = false;
                } else {
                    clockSise = true;
                }
            }

            public function get selectNode():Node
            {
                return _selectNode;
            }

            public function set selectNode(value:Node):void
            {
                if(this.selectNode==value){
                    return;
                }
                _selectNode = value;
                if(this.selectNode==null){
                    _needStop = false;
                    timer.delay = 30;
                    if(!timer.running){
                        timer.start();
                    }
                }else{
                    var rect:Rectangle = indexRectMap[this.selectNode] as Rectangle;
                    var left:Boolean = (rect.x+rect.width/2)<network.width/2;
                    if(left){
                        clockSise = false;
                    }else{
                        clockSise = true;
                    }
                    var index:int = rotationList.getItemIndex(this.selectNode);

                    var size:int = this.rotationList.count;
                    var step:Number = 360/size;
                    _stopAngle = 90 - index * step;
                    _needStop = true;
                    timer.delay = 5;
                    if(!timer.running){
                        timer.start();
                    }
                }
            }

            public function start():void{
                timer.start();
            }
            public function stop():void{
                if(timer!=null){
                    timer.stop();
                }
            }

            public function get startAngle():Number
            {
                return _startAngle;
            }

            public function set startAngle(value:Number):void
            {
                _startAngle = (value+360)%360;
                this.measureRotation();
            }

            public function get rotationList():Collection
            {
                return _rotationList;
            }

            public function set rotationList(value:Collection):void
            {
                _rotationList = value;
                this.box.layerBox.clear();
                var size:int = this.rotationList.count;
                for(var i:int = 0;i<size;i++){
                    var l:Layer = new Layer("r:"+i);
                    box.layerBox.add(l);
                }
                this.measureRotation();
            }
            private function measureRotation():void{
                rectIndexMap = {};
                indexRectMap = {};
                rList.clear();
                var size:int = this.rotationList.count;
                if(size==0){
                    return;
                }
                var w:Number = this.network.width;
                var h:Number = this.network.height;

                var fw:Number = 1.0 / 3 * w;
                var bw:Number = 1.0 / 6 * w;
                var fh:Number = h / 2.5;
                var bh:Number = h / 7.0;

                var m:Number = (fw - bw) / 4;
                var cw:Number = m * 2 + bw;
                var halfcw:Number = cw / 2;
                var x:Number = halfcw + 15;
                w = w - halfcw * 2 - 30;
                var y:Number = bh / 2 + 10;
                h = h - fh / 2 - bh / 2 - 20;

                var step:Number = 360.0 / size;
                for(var i:int = 0;i<size;i++){
                    var n:Node =  this.rotationList.getItemAt(i) as Node;
                    var p:Point = this.getPointAtEllipse(x,y,w,h,startAngle+step*i);
                    var px:Number = p.x;
                    var py:Number = p.y;
                    var pm:Number = (py - y) / h * (fw - bw) / 2;
                    var ww:Number = pm * 2 + bw;
                    var hh:Number = (py - y) / h * (fh - bh) + bh;
                    var rect:Rectangle = new Rectangle(px - ww / 2, py - hh / 2, ww, hh);
                    n.setSize(rect.width,rect.height);
                    n.setCenterLocation(px,py);
                    rectIndexMap[rect] = n;
                    indexRectMap[n] = rect;
                    rList.addItem(rect);
                }
                rList.sort(rectSort);

                for(var j:int = 0;j<size;j++){
                    var rr:Rectangle = rList.getItemAt(j) as Rectangle;
                    var nn:Node = rectIndexMap[rr];
                    nn.layerID = "r:"+j;
                }
            }

            private function rectSort(r1:Rectangle,r2:Rectangle):int{
                if (r1.width> r2.width) {
                    return 1;
                }
                if (r1.width < r2.width) {
                    return -1;
                }
                return 0;
            }

            public function  getPointAtEllipse(x:Number,   y:Number,   w:Number,   h:Number,   angled:Number):Point {
                var angle:Number =angled / 180.0 * Math.PI;
                var px:Number = x + (Math.cos(angle) * 0.5 + 0.5) * w;
                var py:Number = y + (Math.sin(angle) * 0.5 + 0.5) * h;
                return new Point(px, py);
            }

            private function init():void{
                timer=new Timer(30);
                timer.addEventListener(TimerEvent.TIMER,function():void{
                    if(clockSise){
                        startAngle = startAngle+1;
                    }else{
                        startAngle = startAngle-1;
                    }
                    if(_needStop){
                        var abs:Number = Math.abs(startAngle-(_stopAngle+360)%360);
                        if(abs<2){
                            timer.stop();
                        }
                    }
                });
                network.addEventListener(MouseEvent.MOUSE_MOVE,function(e:MouseEvent):void{
                    var p:Point = network.getLogicalPoint(e);
                    resetClockSize(p);
                });
                network.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent):void{
                    var p:Point = network.getLogicalPoint(e);
                    var element:IElement = network.getElementByMouseEvent(e);
                    selectNode = element as Node;
                    resetClockSize(p);
                });
                network.addEventListener(ResizeEvent.RESIZE,function():void{
                    measureRotation();
                });
            }

            private function test():void{
                init();
                Utils.registerImageByClass("p1", p1);
                Utils.registerImageByClass("p2", p2);
                Utils.registerImageByClass("p3", p3);
                Utils.registerImageByClass("p4", p4);
                Utils.registerImageByClass("p5", p5);
                Utils.registerImageByClass("p6", p6);
                Utils.registerImageByClass("p7", p7);
                Utils.registerImageByClass("p8", p8);
                var list:Collection = new Collection();
                for(var i:int = 1;i<9;i++){
                    var sub:Node = new Node();
                    sub.setStyle(Styles.SELECT_STYLE,Consts.SELECT_STYLE_BORDER);
                    sub.setStyle(Styles.IMAGE_STRETCH,Consts.STRETCH_FILL);
                    sub.setStyle(Styles.SELECT_COLOR,"0x00ff00");

                    sub.setStyle(Styles.LABEL_POSITION,Consts.POSITION_CENTER);
                    sub.image = "p"+i;
                    sub.name = "sub"+i
                    list.addItem(sub);
                    box.add(sub);
                }
                this.rotationList = list;
                network.elementBox = box;
                this.start();
            }

        ]]>
    </mx:Script>
    <ns:Network id="network" width="100%" height="100%" backgroundColor="0xffffff">

    </ns:Network>
</mx:Application>

No comments:

Post a Comment