打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
svg webtopo原型8
分类: web编程 svg 2012-07-05 10:07 669人阅读 评论(0) 收藏 举报

这回是真正的考验了,要实现设备的鼠标拖曳功能。

这个功能理论上比较简单,但是为了兼容性,几乎吐血。

实现的方法有很多,这里仅列举一种。

核心就在于坐标变换,主要有三点注意

针对ieembed,需要注意设置wmode="Transparent"属性,这样可以不影响页面的鼠标事件。

再有就是IE/asv不支持offsetX方法,所以需要自行设法计算鼠标点击位置相对设备的坐标。

Ieoperaclientx的取值不同ie是相对svg元素的坐标,opera是相对整个页面的坐标,因此移动函数采用了不同的算法。

6dev.htm

  1. <html xmlns="http://www.w3.org/1999/xhtml">  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=gb2312">  
  4. <title>  
  5. 设备  
  6. </title>  
  7.  <meta http-equiv="X-UA-Compatible" content="chrome=1">  
  8. <!-- legengd.html  
  9.  1.显示设备(文字、图片)  
  10.  2.拖动  
  11. -->  
  12. </head>  
  13. <script type="text/javascript" language="javascript" src="./js/moveObjs.js"></script>  
  14. <script type="text/javascript" language="javascript" src="./js/svgutil.js"></script>  
  15. <script type="text/javascript" language="javascript" src="./js/topo.js"></script>  
  16.   
  17. <script>  
  18.   
  19. </script>  
  20.   
  21. <body bgcolor="#ffffff">  
  22.   
  23.   
  24. <br>  
  25. <button onclick="show()">开始</button><br>  
  26. <button onclick="zoomby(0.5)">缩小2倍cor</button>  
  27. <button onclick="zoomby(2)">放大 2倍cor</button>  
  28. <button onclick="zoom(1,300,300)">还原</button><br>  
  29. <button onclick="showsrc()">源码</button><br>  
  30. <button onclick="movetest()">移动</button><br>  
  31. <div id="divsvg" style="position: absolute;top:180;left:0"></div>  
  32. <div id="pos"></div>  
  33. <div id="pos1"></div>  
  34. </body>  
  35. <script>  
  36.   
  37.   
  38. var svg;  
  39. var svgw=400;  
  40. var svgh=300;  
  41. //var svgdoc;  
  42. var plat;  
  43.   
  44. function show(){  
  45.    
  46.  svg=initSVG(svgw,svgh);  
  47.  //延迟一下,最小是10ms  
  48.  var tidst=window.setTimeout(show1,20);  
  49. }  
  50.   
  51. function show1(){  
  52.  //var svg;  
  53.  //svg=initSVG(200,200);  
  54.  //var svgdoc;  
  55.  svgdoc=getSVGDocument(svg);  
  56.  plat=getrootg(svg,svgdoc);  
  57.    
  58.   
  59.  //生成一个设备  
  60.  curentStyle="stroke:black;fill:green";  
  61.  var device=createDev("DEV00005",100,100,29.0,17.0,"./image/DEV_IP_R.gif","XM-BB-GSR12816-D-1.MAN(61.154.237.12)");  
  62.  }  
  63.    
  64.  function movetest(){  
  65.  //验证一下svg的group能否整体移动  
  66.   var svgdoc=getSVGDocument(svg);  
  67.   var plat=svgdoc.getElementById('DEV00005');  
  68.     
  69.   plat.setAttribute("transform","translate(0,50)");  
  70.           
  71. }  
  72.   
  73. </script>  
  74. </html>  

相关的操作进行了一下封装

设备相关的。topo.js


 

  1. //3.二级函数  
  2. //这里的位置和大小是由摆放算法确定的  
  3.   
  4. //节点。别名,叫设备有点太具体  
  5. function createNode(id,x,y,width,height,imageSrc,name,target,style){  
  6.     var node=createDev(id,x,y,width,height,imageSrc,name,target,style);  
  7.     return node;  
  8. }     
  9.   
  10. function createDev(id,left,top,width,height,imageSrc,name,target,style){  
  11.       
  12.     //设备首先包含一个group  
  13.     style="fill:red";  
  14.   var group=createGroup(id,left,top,width,height ,name,style);  
  15.   //group.setAttribute("hasAlarm",false);  
  16.   //if (target == undefined){  
  17.   if (!target){  
  18.     var svgdoc1=getSVGDocument(svg);  
  19.     var plat1=getrootg(svg,svgdoc1);  
  20.     plat1.appendChild(group);  
  21.   }  
  22.   else{  
  23.     target.appendChild(group);  
  24.   }  
  25.   
  26.     
  27.   //在svg中,元素位置都是相对svg的。文本显示在起点的右上,矩形和图片显示在右下  
  28.   //设备的图片  
  29.   var image=createImage(top,left,width,height,imageSrc);  
  30.     
  31.   group.appendChild(image);  
  32.   
  33.   //设备的名称  
  34.   style="fill:blue;cursor:move";  
  35.   var namebox=createText(top,left,name,style);   
  36.   group.appendChild(namebox);  
  37.     
  38.   //相对坐标移动  
  39.   //移动的相关事件  
  40.   if(isIE){  
  41.   
  42.     group.setAttribute("onmousedown","dragie(evt,this)");  
  43.      }  
  44.   else{  
  45.     group.setAttribute("onmousedown","drago(evt,this)");  
  46.   }  
  47.     
  48.     
  49.   //可选,用于绝对坐标移动  
  50.     group.movetopos=function(ckx,cky){  
  51.       
  52.     group.setAttribute("x",ckx);  
  53.     group.setAttribute("y",cky);  
  54.     image.setAttribute("x",ckx);  
  55.     image.setAttribute("y",cky);  
  56.     namebox.setAttribute("x",ckx);  
  57.     namebox.setAttribute("y",cky);  
  58.   }  
  59.   return group;  
  60. }  
  61.   
  62. //创建电路  
  63. //连线的位置需要根据设备的起点和大小进行计算,top对应y,left对应x.top+weight/2  
  64.   
  65. function createCircuit(id,x1,y1,x2,y2,name,title,id1,id2,target,style){  
  66.     var line=createLink(id,x1,y1,x2,y2,name,title,target,style);  
  67.     //起点  
  68.     var svgdoc1=getSVGDocument(svg);  
  69.   
  70.     var fromObj=svgdoc1.getElementById(id1);  
  71.   
  72.   //var fromLinks=fromObj.getAttribute("fromLinks");  
  73.   var fromLinks=fromObj.fromLinks;  
  74.   if(fromLinks==null){  
  75.     fromLinks=new Array();  
  76.       
  77.   }  
  78.   //追加到数组末尾,便于拖动时计算  
  79.   //alert(fromLinks.length);  
  80.   fromLinks[fromLinks.length]=line;  
  81.   //fromObj.setAttribute("fromLinks",fromLinks);  
  82.   fromObj.fromLinks=fromLinks;  
  83.   //alert(fromLinks.length);  
  84.   //var fromLink=fromObj.fromLinks;;  
  85.   //alert(fromLink[0].id);  
  86.     //终点  
  87.      var toObj=svgdoc1.getElementById(id2);  
  88.   var tolinks=toObj.toLinks;  
  89.   if(tolinks==null){  
  90.     tolinks=new Array();  
  91.     toObj.setAttribute("toLinks",tolinks);  
  92.   }  
  93.    //追加到数组末尾,便于拖动时计算  
  94.   tolinks[tolinks.length]=line;  
  95.   toObj.toLinks=tolinks;  
  96.     
  97.     //位置和大小。  
  98.   line.setAttribute("hasAlarm",false);  
  99.     
  100.       
  101.     return line;  
  102. }  
  103.   
  104. //创建线型  
  105. function createStroke(line){  
  106.     var curstyle=line.getAttribute("oristyle");  
  107.     var newstyle=";stroke-dasharray: 9, 5";  
  108.     var style=curstyle+newstyle;  
  109.     //alert(style);  
  110.     line.setAttribute("style",style);  
  111. }  
  112. //删除线型  
  113. function removeStroke(line){  
  114.   var curstyle=line.getAttribute("oristyle");  
  115.   //alert(curstyle);  
  116.   line.setAttribute("style",curstyle);  
  117. }  


 移动相关的movobjs.js

这个算法参照了网上的一个经典方法,非常简洁。

 

[javascript] view plaincopy
  1. var xx=0,yy=0;  
  2. var moveobj=null,ckleft=0,cktop=0,ckw=0,ckhei=0,ckto="";  
  3. var tempx,tempy;  
  4. var showDevRelaCir=true;  
  5. var fromLinks=null;  
  6. var toLinks=null;  
  7. var moving;  
  8.   
  9. function dealLineWhenChoose(moveobj){  
  10.         //处理设备相关的电路信息  
  11.           
  12.     //点中设备的相关电路变虚线  
  13.     if(showDevRelaCir==true){  
  14.           
  15.         //清除前次的线型  
  16.       if(fromLinks!=null)  
  17.         for(var i=0;i<fromLinks.length;i++){  
  18.           removeStroke(fromLinks[i]);  
  19.         }  
  20.       if(toLinks!=null)  
  21.         for(var i=0;i<toLinks.length;i++){  
  22.           removeStroke(toLinks[i]);  
  23.         }  
  24.         //重画线型  
  25.        fromLinks=moveobj.fromLinks;  
  26.       // alert(fromLinks.length);  
  27.        if(fromLinks!=null)  
  28.         for(var i=0;i<fromLinks.length;i++){  
  29.           createStroke(fromLinks[i]);  
  30.         }  
  31.        toLinks=moveobj.toLinks;  
  32.         if(toLinks!=null)  
  33.           for(var i=0;i<toLinks.length;i++){  
  34.             createStroke(toLinks[i]);  
  35.           }  
  36.         }  
  37. }  
  38.   
  39. //js移动设备  
  40. function movdev(moveobj,ckx,cky){  
  41.   
  42.       
  43.     if(moveobj!=null){            
  44.           moveobj.setAttribute("transform","translate("+ckx+","+cky+")");  
  45.        
  46.      //移动相关连线  
  47.        
  48.     // var x=parseInt(moveobj.getAttribute("x"))+parseInt(moveobj.width)/2;  
  49.      //var y=parseInt(moveobj.getAttribute("y"))+parseInt(moveobj.height)/2;  
  50.      var x=parseInt(moveobj.getAttribute("x"))+ckx+parseInt(moveobj.getAttribute("width"))/2;  
  51.    
  52.      var y=parseInt(moveobj.getAttribute("y"))+cky+parseInt(moveobj.getAttribute("height"))/2;  
  53.      //alert(x+","+y);  
  54.     var fromLinks=moveobj.fromLinks;  
  55.      if(fromLinks!=null)  
  56.       for(var i=0;i<fromLinks.length;i++){  
  57.         fromLinks[i].setAttribute("x1",x);  
  58.         fromLinks[i].setAttribute("y1",y);  
  59.          //fromLinks[i].setAttribute("transform","translate("+ckx+","+cky+")");  
  60.         //dealLineWhenObjMove(fromLinks[i]);  
  61.       }  
  62.      var toLinks=moveobj.toLinks;  
  63.      if(toLinks!=null)  
  64.       for(var i=0;i<toLinks.length;i++){  
  65.         toLinks[i].setAttribute("x2",x);  
  66.         toLinks[i].setAttribute("y2",y);  
  67.         //toLinks[i].setAttribute("transform","translate("+ckx+","+cky+")");  
  68.         //dealLineWhenObjMove(toLinks[i]);  
  69.       }  
  70.     }  
  71.   
  72. }  
  73.   
  74. //方法1,使用translate方法进行相对移动.  
  75. function drago(evt,obj){  
  76.       
  77.       //获得事件的父对象(group)  
  78.       var oc=evt.target;  
  79.       var o=evt.target.parentNode;  
  80.         var d=document;  
  81.         //var d=document.getElementById('divsvg');  
  82.         //var d=getSVGDocument(svg);  
  83.         if(!evt)evt=window.event;  
  84.           
  85.         //记录down点击的相对位置(注意,是相对svg/divsvg的位置)  
  86.         var x=evt.layerX?evt.layerX:evt.offsetX,y=evt.layerY?evt.layerY:evt.offsetY;  
  87.         //获得svg的初始位置,用于计算坐标  
  88.         var divsvg=document.getElementById('divsvg');  
  89.         var dtop=delPx(divsvg.style.top);  
  90.         var dleft=delPx(divsvg.style.left);  
  91.           
  92.           
  93.         //记录初始的位置信息  
  94.         var ttx=o.getAttribute("x");  
  95.         var tty=o.getAttribute("y");  
  96.           
  97.       
  98.           
  99.         dealLineWhenChoose(o);  
  100.       
  101.           
  102.         if(o.setCapture)  
  103.             o.setCapture();  
  104.         else if(window.captureEvents)  
  105.             window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);  
  106.   
  107.     //opera的svg不会遮挡document的事件,但是ie会  
  108.         d.onmousemove=function(a){  
  109.             if(!a)a=window.event;  
  110.             if(!a.pageX)a.pageX=a.clientX;  
  111.             if(!a.pageY)a.pageY=a.clientY;  
  112.               
  113.             //目标的相对位置(注意,要考虑svg的初始位置影响)  
  114.             var tx=a.pageX-x-dleft-ttx,ty=a.pageY-y-dtop-tty;  
  115.                   
  116.               
  117.           
  118.             //这个每次都是从最初位置开始移动。  
  119.             movdev(o,tx,ty);  
  120.         };  
  121.   
  122.         d.onmouseup=function(){  
  123.             if(o.releaseCapture){  
  124.                   
  125.                 o.releaseCapture();  
  126.             }  
  127.             else if(window.captureEvents)  
  128.                 window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);  
  129.             d.onmousemove=null;  
  130.             d.onmouseup=null;  
  131.         };  
  132.   
  133. }  
  134.   
  135.   
  136. //方法1,使用translate方法进行相对移动.  
  137. function dragie(evt,obj){  
  138.       
  139.       //获得事件的父对象(group)  
  140.       var oc=evt.target;  
  141.       var o=evt.target.parentNode;  
  142.         var d=document;  
  143.         if(!evt)evt=window.event;  
  144.           
  145.           
  146.         //获得svg的初始位置,用于计算坐标  
  147.         var divsvg=document.getElementById('divsvg');  
  148.         var dtop=delPx(divsvg.style.top);  
  149.         var dleft=delPx(divsvg.style.left);  
  150.           
  151.           
  152.         //记录初始的位置信息(不用)  
  153.         var ttx=o.getAttribute("x");  
  154.         var tty=o.getAttribute("y");  
  155.           
  156.         xx=evt.clientX;  
  157.     yy=evt.clientY;  
  158.           
  159.          var tran;  
  160.    var trans=o.getAttribute("transform");  
  161.    if(trans){  
  162.     tran=trans.substring(10,trans.length-1);  
  163.     var tranpara=tran.split(",");  
  164.     ckleft=parseInt(tranpara[0]);  
  165.     cktop=parseInt(tranpara[1]);  
  166.    }  
  167.      
  168.           
  169.       
  170.           
  171.         if(o.setCapture)  
  172.             o.setCapture();  
  173.         else if(window.captureEvents)  
  174.             window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);  
  175.               
  176.             dealLineWhenChoose(o);  
  177.   
  178.     //opera的svg不会遮挡document的事件,ie需要设置成透明  
  179.         d.onmousemove=function(a){  
  180.             if(!a)a=window.event;  
  181.             if(!a.pageX)a.pageX=a.clientX;  
  182.             if(!a.pageY)a.pageY=a.clientY;  
  183.               
  184.             //目标的相对位置(注意,要考虑svg的初始位置影响)  
  185.       //由于ie不能取到初始的offset,所以算法和opera不同,但是效果相同  
  186.       //var tx=a.pageX-x-dleft-ttx,ty=a.pageY-y-dtop-tty;  
  187.             var tx=a.pageX+ckleft-xx-dleft,ty=a.pageY+cktop-yy-dtop;  
  188.                   
  189.               
  190.           
  191.             //这个每次都是从最初位置开始移动。  
  192.             movdev(o,tx,ty);  
  193.         };  
  194.   
  195.         d.onmouseup=function(){  
  196.             if(o.releaseCapture){  
  197.                   
  198.                 o.releaseCapture();  
  199.             }  
  200.             else if(window.captureEvents)  
  201.                 window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);  
  202.             d.onmousemove=null;  
  203.             d.onmouseup=null;  
  204.         };  
  205.   
  206. }  
  207.   
  208.           
  209.   
  210.           
  211. function delPx(pos){  
  212.     return (parseInt(pos.substring(0,pos.length-2)));  
  213. }  


 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
HTML页面中的DOM操作
svg编辑器
面向浏览器的动态 SVG
SVG
引用 js在IE和FF的区别 - Neil的日志 - 网易博客
Javascript 多浏览器兼容性问题及解决方案
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服