最近有客户提了一个网元动态旋转的需求,用TWaver实现起来还是很方便的,效果如下图所示:
主要实现功能:
1:网元动态旋转
2:网元选中效果,被选中网元快速转到最前端后停止旋转,取消选中自动重启旋转
3:根据鼠标位置自动调整旋转方向
4:可以在程序中修改fw/bw/fh/bh调整图片显示效果。
代码如下所示:
<?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>