TWaver - 專注UI技術(shù)

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          最近用戶有個(gè)比較“變態(tài)”的需求:從工具欄上將節(jié)點(diǎn)拖入拓?fù)鋱D中時(shí),如果鼠標(biāo)下面是Link,就將節(jié)點(diǎn)插入這條Link之間;而且鼠標(biāo)在拖拽過程中,鼠標(biāo)下面的link呈現(xiàn)凸起效果。

          在Link之間插入節(jié)點(diǎn)好說,可以刪除這條Link再添加兩條Link,不過凸起效果就有點(diǎn)費(fèi)勁了。這里用TWaver Flex的ShapeLink實(shí)現(xiàn)比較滿意的效果:


          大概思路是:
          1. 監(jiān)聽network的DragEvent.DRAG_OVER事件,用network#getElementsByDisplayObject方法判斷鼠標(biāo)下面是否有Link。如果有就將這個(gè)Link變成透明(link.setStyle(Styles.LINK_ALPHA, 0);),然后加入一條ShapeLink;如果沒有就將之前變成透明的Link還原,并刪除ShapeLink。具體代碼見updateMark以及removeMark方法:

           1 private function updateMark(link:Link, data:Object, point:Point):void {
           2     if(!network.elementBox.contains(markLink)){
           3         markLink.fromNode = link.fromNode;
           4         markLink.toNode = link.toNode;
           5         markLink.setStyle(Styles.SHAPELINK_TYPE, Consts.SHAPELINK_TYPE_QUADTO);
           6         markLink.setStyle(Styles.LINK_WIDTH, link.getStyle(Styles.LINK_WIDTH));
           7         markLink.setStyle(Styles.LINK_COLOR, link.getStyle(Styles.LINK_COLOR));
           8         markLink.setStyle(Styles.LINK_ALPHA, link.getStyle(Styles.LINK_ALPHA));
           9 
          10         network.elementBox.add(markLink);
          11         lastLink = link;
          12         link.setStyle(Styles.LINK_ALPHA, 0);
          13     }
          14 
          15     var points:Collection = new Collection();
          16 
          17     var fromCenter:Point = markLink.fromNode.centerLocation;
          18     var toCenter:Point = markLink.toNode.centerLocation;
          19     var radius:Number = Math.sqrt(data.width*data.width + data.height*data.height)/2;
          20     var crossPoints:Object = getCrossPoints(fromCenter, toCenter, point, radius*2);
          21     if (crossPoints){
          22         if(fromCenter.x<toCenter.x){
          23             points.addItem(crossPoints.p2);
          24             points.addItem(crossPoints.p2);
          25         }else{
          26             points.addItem(crossPoints.p1);
          27             points.addItem(crossPoints.p1);
          28         }
          29 
          30         var crossPoint:Point = new Point(crossPoints.p1.x + (crossPoints.p2.x-crossPoints.p1.x)/2,
          31             crossPoints.p1.y + (crossPoints.p2.y-crossPoints.p1.y)/2);
          32         var controlPoints:Object = getCrossPoints(crossPoint, point, point, radius*3);
          33         if(controlPoints){
          34             if(crossPoint.y >= point.y){
          35                 points.addItem(controlPoints.p2);
          36             }else{
          37                 points.addItem(controlPoints.p1);
          38             }
          39         }else{
          40             if(point.y>=fromCenter.y){
          41                 point.y = point.y - radius * 3;
          42             }else{
          43                 point.y = point.y + radius * 3;
          44             }
          45             points.addItem(point);
          46         }
          47         if(fromCenter.x<toCenter.x){
          48             points.addItem(crossPoints.p1);
          49             points.addItem(crossPoints.p1);
          50         }else{
          51             points.addItem(crossPoints.p2);
          52             points.addItem(crossPoints.p2);
          53         }
          54     }else{
          55         points.addItem(fromCenter);
          56     }
          57     markLink.points = points;
          58 }
          59 
          60 private function removeMark(moving:Boolean):void {
          61     if(network.elementBox.contains(markLink)){
          62         var fromNode:Node = markLink.fromNode;
          63         var toNode:Node = markLink.toNode;
          64         network.elementBox.remove(markLink);
          65         if(lastLink && moving){
          66             lastLink.setStyle(Styles.LINK_ALPHA, markLink.getStyle(Styles.LINK_ALPHA));
          67             lastLink = null;
          68         }
          69     }
          70 }
          71 

           

          2. 最關(guān)鍵的是如何確定ShapeLink的points。這里的核心是計(jì)算圓和直線的交點(diǎn)。具體代碼見getCrossPoints方法:

           1 private function getCrossPoints(p1:Point, p2:Point, circleCenter:Point, radius:Number):Object{
           2     var line_p1_x:Number = p1.x;
           3     var line_p1_y:Number = p1.y;
           4     var line_p2_x:Number = p2.x;
           5     var line_p2_y:Number = p2.y;
           6     var circle_center_x:Number = circleCenter.x;
           7     var circle_center_y:Number = circleCenter.y;
           8     var circle_radius:Number = radius;
           9     var line_k:Number =(line_p2_y-line_p1_y)/(line_p2_x-line_p1_x);
          10     var line_b:Number =line_p1_y-line_k*line_p1_x;
          11     var a:Number =1+line_k*line_k;
          12     var b:Number =-2*circle_center_x+2*line_k*line_b-2*line_k*circle_center_y;
          13     var c:Number =circle_center_x*circle_center_x+(line_b-circle_center_y)*(line_b-circle_center_y)-circle_radius*circle_radius;
          14     var delta:Number =b*b-4*a*c;
          15     var x1:Number =(-b+Math.sqrt(delta))/(2*a);
          16     var x2:Number =(-b-Math.sqrt(delta))/(2*a);
          17     var y1:Number =line_k*x1+line_b;
          18     var y2:Number =line_k*x2+line_b;
          19 
          20     if(delta>=0){
          21         return {p1: new Point(x1, y1), p2: new Point(x2, y2)};
          22     }else{
          23         return null;
          24     }
          25 }
          26 

           

          3. 在DragEvent.DRAG_DROP事件里,刪除ShapeLink并創(chuàng)建兩條Link。

          源碼下載

           


          評(píng)論

          # re: Flex下實(shí)現(xiàn)拖動(dòng)節(jié)點(diǎn)時(shí),連線拱起的效果  回復(fù)  更多評(píng)論   

          2011-02-17 22:34 by 奇幻修真小說
          最關(guān)鍵的是如何確定ShapeLink的points。這里的核心是計(jì)算圓和直線的交點(diǎn)。

          # re: Flex下實(shí)現(xiàn)拖動(dòng)節(jié)點(diǎn)時(shí),連線拱起的效果  回復(fù)  更多評(píng)論   

          2011-02-20 17:09 by 好店8
          確實(shí)是比較變態(tài)的要求。。。項(xiàng)目做多了,總會(huì)碰到各樣奇怪的要求。。

          # re: Flex下實(shí)現(xiàn)拖動(dòng)節(jié)點(diǎn)時(shí),連線拱起的效果  回復(fù)  更多評(píng)論   

          2011-02-21 09:50 by qiuyunanjichong
          這需求不是一般變態(tài)

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 丰原市| 甘泉县| 德钦县| 乌鲁木齐市| 酒泉市| 万全县| 鄂州市| 威信县| 上杭县| 苍山县| 都江堰市| 新绛县| 大港区| 务川| 三江| 博罗县| 桐柏县| 朝阳市| 广宗县| 延长县| 安阳市| 三都| 阳东县| 大城县| 泾川县| 宁德市| 青川县| 深州市| 六枝特区| 柘荣县| 萨嘎县| 铜鼓县| 云林县| 长海县| 柯坪县| 巴彦淖尔市| 盐边县| 长寿区| 辛集市| 寻甸| 安西县|