svg webtopo原型8 -拖曳
来源:互联网 发布:怀化广电网络 编辑:程序博客网 时间:2024/05/16 15:03
这回是真正的考验了,要实现设备的鼠标拖曳功能。
这个功能理论上比较简单,但是为了兼容性,几乎吐血。
实现的方法有很多,这里仅列举一种。
核心就在于坐标变换,主要有三点注意
针对ie的embed,需要注意设置wmode="Transparent"属性,这样可以不影响页面的鼠标事件。
再有就是IE/asv不支持offsetX方法,所以需要自行设法计算鼠标点击位置相对设备的坐标。
Ie和opera对clientx的取值不同ie是相对svg元素的坐标,opera是相对整个页面的坐标,因此移动函数采用了不同的算法。
6dev.htm
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>设备</title> <meta http-equiv="X-UA-Compatible" content="chrome=1"><!-- legengd.html 1.显示设备(文字、图片) 2.拖动--></head><script type="text/javascript" language="javascript" src="./js/moveObjs.js"></script><script type="text/javascript" language="javascript" src="./js/svgutil.js"></script><script type="text/javascript" language="javascript" src="./js/topo.js"></script><script></script><body bgcolor="#ffffff"><br><button onclick="show()">开始</button><br><button onclick="zoomby(0.5)">缩小2倍cor</button><button onclick="zoomby(2)">放大 2倍cor</button><button onclick="zoom(1,300,300)">还原</button><br><button onclick="showsrc()">源码</button><br><button onclick="movetest()">移动</button><br><div id="divsvg" style="position: absolute;top:180;left:0"></div><div id="pos"></div><div id="pos1"></div></body><script>var svg;var svgw=400;var svgh=300;//var svgdoc;var plat;function show(){ svg=initSVG(svgw,svgh); //延迟一下,最小是10ms var tidst=window.setTimeout(show1,20);}function show1(){ //var svg; //svg=initSVG(200,200); //var svgdoc; svgdoc=getSVGDocument(svg); plat=getrootg(svg,svgdoc); //生成一个设备 curentStyle="stroke:black;fill:green"; 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)"); } function movetest(){ //验证一下svg的group能否整体移动 var svgdoc=getSVGDocument(svg); var plat=svgdoc.getElementById('DEV00005'); plat.setAttribute("transform","translate(0,50)");}</script></html>
相关的操作进行了一下封装
设备相关的。topo.js
//3.二级函数//这里的位置和大小是由摆放算法确定的//节点。别名,叫设备有点太具体function createNode(id,x,y,width,height,imageSrc,name,target,style){var node=createDev(id,x,y,width,height,imageSrc,name,target,style);return node;}function createDev(id,left,top,width,height,imageSrc,name,target,style){//设备首先包含一个groupstyle="fill:red"; var group=createGroup(id,left,top,width,height ,name,style); //group.setAttribute("hasAlarm",false); //if (target == undefined){ if (!target){ var svgdoc1=getSVGDocument(svg); var plat1=getrootg(svg,svgdoc1); plat1.appendChild(group); } else{ target.appendChild(group); } //在svg中,元素位置都是相对svg的。文本显示在起点的右上,矩形和图片显示在右下 //设备的图片 var image=createImage(top,left,width,height,imageSrc); group.appendChild(image); //设备的名称 style="fill:blue;cursor:move"; var namebox=createText(top,left,name,style); group.appendChild(namebox); //相对坐标移动 //移动的相关事件 if(isIE){ group.setAttribute("onmousedown","dragie(evt,this)"); } else{ group.setAttribute("onmousedown","drago(evt,this)"); } //可选,用于绝对坐标移动 group.movetopos=function(ckx,cky){ group.setAttribute("x",ckx); group.setAttribute("y",cky); image.setAttribute("x",ckx); image.setAttribute("y",cky); namebox.setAttribute("x",ckx); namebox.setAttribute("y",cky); } return group;}//创建电路//连线的位置需要根据设备的起点和大小进行计算,top对应y,left对应x.top+weight/2function createCircuit(id,x1,y1,x2,y2,name,title,id1,id2,target,style){var line=createLink(id,x1,y1,x2,y2,name,title,target,style);//起点var svgdoc1=getSVGDocument(svg);var fromObj=svgdoc1.getElementById(id1); //var fromLinks=fromObj.getAttribute("fromLinks"); var fromLinks=fromObj.fromLinks; if(fromLinks==null){ fromLinks=new Array(); } //追加到数组末尾,便于拖动时计算 //alert(fromLinks.length); fromLinks[fromLinks.length]=line; //fromObj.setAttribute("fromLinks",fromLinks); fromObj.fromLinks=fromLinks; //alert(fromLinks.length); //var fromLink=fromObj.fromLinks;; //alert(fromLink[0].id);//终点 var toObj=svgdoc1.getElementById(id2); var tolinks=toObj.toLinks; if(tolinks==null){ tolinks=new Array(); toObj.setAttribute("toLinks",tolinks); } //追加到数组末尾,便于拖动时计算 tolinks[tolinks.length]=line; toObj.toLinks=tolinks; //位置和大小。 line.setAttribute("hasAlarm",false); return line;}//创建线型function createStroke(line){var curstyle=line.getAttribute("oristyle");var newstyle=";stroke-dasharray: 9, 5";var style=curstyle+newstyle;//alert(style);line.setAttribute("style",style);}//删除线型function removeStroke(line){ var curstyle=line.getAttribute("oristyle"); //alert(curstyle); line.setAttribute("style",curstyle);}
移动相关的movobjs.js
这个算法参照了网上的一个经典方法,非常简洁。
var xx=0,yy=0;var moveobj=null,ckleft=0,cktop=0,ckw=0,ckhei=0,ckto="";var tempx,tempy;var showDevRelaCir=true;var fromLinks=null;var toLinks=null;var moving;function dealLineWhenChoose(moveobj){//处理设备相关的电路信息//点中设备的相关电路变虚线if(showDevRelaCir==true){//清除前次的线型 if(fromLinks!=null) for(var i=0;i<fromLinks.length;i++){ removeStroke(fromLinks[i]); } if(toLinks!=null) for(var i=0;i<toLinks.length;i++){ removeStroke(toLinks[i]); } //重画线型 fromLinks=moveobj.fromLinks; // alert(fromLinks.length); if(fromLinks!=null) for(var i=0;i<fromLinks.length;i++){ createStroke(fromLinks[i]); } toLinks=moveobj.toLinks; if(toLinks!=null) for(var i=0;i<toLinks.length;i++){ createStroke(toLinks[i]); } }}//js移动设备function movdev(moveobj,ckx,cky){ if(moveobj!=null){ moveobj.setAttribute("transform","translate("+ckx+","+cky+")"); //移动相关连线 // var x=parseInt(moveobj.getAttribute("x"))+parseInt(moveobj.width)/2; //var y=parseInt(moveobj.getAttribute("y"))+parseInt(moveobj.height)/2; var x=parseInt(moveobj.getAttribute("x"))+ckx+parseInt(moveobj.getAttribute("width"))/2; var y=parseInt(moveobj.getAttribute("y"))+cky+parseInt(moveobj.getAttribute("height"))/2; //alert(x+","+y); var fromLinks=moveobj.fromLinks; if(fromLinks!=null) for(var i=0;i<fromLinks.length;i++){ fromLinks[i].setAttribute("x1",x); fromLinks[i].setAttribute("y1",y); //fromLinks[i].setAttribute("transform","translate("+ckx+","+cky+")"); //dealLineWhenObjMove(fromLinks[i]); } var toLinks=moveobj.toLinks; if(toLinks!=null) for(var i=0;i<toLinks.length;i++){ toLinks[i].setAttribute("x2",x); toLinks[i].setAttribute("y2",y); //toLinks[i].setAttribute("transform","translate("+ckx+","+cky+")"); //dealLineWhenObjMove(toLinks[i]); } }}//方法1,使用translate方法进行相对移动.function drago(evt,obj){ //获得事件的父对象(group) var oc=evt.target; var o=evt.target.parentNode;var d=document;//var d=document.getElementById('divsvg');//var d=getSVGDocument(svg);if(!evt)evt=window.event;//记录down点击的相对位置(注意,是相对svg/divsvg的位置)var x=evt.layerX?evt.layerX:evt.offsetX,y=evt.layerY?evt.layerY:evt.offsetY;//获得svg的初始位置,用于计算坐标var divsvg=document.getElementById('divsvg');var dtop=delPx(divsvg.style.top);var dleft=delPx(divsvg.style.left);//记录初始的位置信息var ttx=o.getAttribute("x");var tty=o.getAttribute("y");dealLineWhenChoose(o);if(o.setCapture)o.setCapture();else if(window.captureEvents)window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); //opera的svg不会遮挡document的事件,但是ie会d.onmousemove=function(a){if(!a)a=window.event;if(!a.pageX)a.pageX=a.clientX;if(!a.pageY)a.pageY=a.clientY;//目标的相对位置(注意,要考虑svg的初始位置影响)var tx=a.pageX-x-dleft-ttx,ty=a.pageY-y-dtop-tty;//这个每次都是从最初位置开始移动。movdev(o,tx,ty);};d.onmouseup=function(){if(o.releaseCapture){o.releaseCapture();}else if(window.captureEvents)window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);d.onmousemove=null;d.onmouseup=null;};}//方法1,使用translate方法进行相对移动.function dragie(evt,obj){ //获得事件的父对象(group) var oc=evt.target; var o=evt.target.parentNode;var d=document;if(!evt)evt=window.event;//获得svg的初始位置,用于计算坐标var divsvg=document.getElementById('divsvg');var dtop=delPx(divsvg.style.top);var dleft=delPx(divsvg.style.left);//记录初始的位置信息(不用)var ttx=o.getAttribute("x");var tty=o.getAttribute("y");xx=evt.clientX; yy=evt.clientY; var tran; var trans=o.getAttribute("transform"); if(trans){ tran=trans.substring(10,trans.length-1); var tranpara=tran.split(","); ckleft=parseInt(tranpara[0]); cktop=parseInt(tranpara[1]); } if(o.setCapture)o.setCapture();else if(window.captureEvents)window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);dealLineWhenChoose(o); //opera的svg不会遮挡document的事件,ie需要设置成透明d.onmousemove=function(a){if(!a)a=window.event;if(!a.pageX)a.pageX=a.clientX;if(!a.pageY)a.pageY=a.clientY;//目标的相对位置(注意,要考虑svg的初始位置影响) //由于ie不能取到初始的offset,所以算法和opera不同,但是效果相同 //var tx=a.pageX-x-dleft-ttx,ty=a.pageY-y-dtop-tty;var tx=a.pageX+ckleft-xx-dleft,ty=a.pageY+cktop-yy-dtop;//这个每次都是从最初位置开始移动。movdev(o,tx,ty);};d.onmouseup=function(){if(o.releaseCapture){o.releaseCapture();}else if(window.captureEvents)window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);d.onmousemove=null;d.onmouseup=null;};}function delPx(pos){return (parseInt(pos.substring(0,pos.length-2)));}
- svg webtopo原型8 -拖曳
- svg webtopo原型7 设备
- svg webtopo原型9- 连线
- svg webtopo原型(1)基本功能
- svg webtopo原型2基本功能,缩放
- svg webtopo原型3 chrome frame
- svg webtopo原型5 基本的事件
- svg webtopo原型(1)基本功能
- svg webtopo原型4-图片的动态显示
- svg webtopo原型6 事件的鼠标属性
- 鼠标拖曳实现svg矩形的任意切分
- 鼠标拖曳实现svg矩形的任意切分
- 使用draggable插件实现对象的拖曳操作8-1
- 拖曳层!
- Treeview拖曳
- 拖曳js
- div拖曳
- html5 拖曳
- inotify in android
- UPnP 协议概述
- 全自动安装微软雅黑字体- Ubuntu
- xcode 4.2下怎么添加framework?
- 郎咸平:中国人正上的四个大当 房产排第一
- svg webtopo原型8 -拖曳
- 一位码农的人生自述(十)------得失
- Cortex-M3 (NXP LPC1788)之ADC数模转换器的应用
- UPNP协议细节(转)
- python 获取当前位置所在的函数名和行号
- android4.0 中如何在app 中拦截HOME键
- 素数筛法的常数优化简单整理
- 什么是阻抗(Electrical impedance)
- Android map API 注册后地图仍然不显示