因为要实现拖拽连线研究了一下基于extjs 和html5的不同实现方法

extjs底层的画图引擎是svg 不知道在html5大潮即将袭来的前夕一贯走在技术前沿的extjs开发团队没有自己封装基于html5的画图引擎,而是选择了svg 。

下边是花了不到一天的时间实现的任意点连线和拖动功能,代码没有优化,稍微乱了点

如果单纯应用canvas进行画图,拖拽是非常麻烦的,我们往往要基于第三方的画图类库,这里实现是基于kineticjs

为了测试方便我使用了双击事件控制拖动还是划线  。

代码

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <style>
  5. body {
  6. margin: 0px;
  7. padding: 0px;
  8. }
  9. canvas {
  10. border: 1px solid #9C9898;
  11. }
  12. </style>
  13. <script type="text/javascript" src="ext/bootstrap.js"></script>
  14. <!-- ENDLIBS -->
  15. <script type="text/javascript" src="ext/ext-all-debug.js"></script>
  16. <script src="js/kinetic-v3.10.2.min.js"></script>
  17. <script>
  18. Ext.onReady(function(){
  19. /**
  20. 自动判断顶点连线算法
  21. */
  22. var stage=new Kinetic.Stage({
  23. container:'container',
  24. width:1000,
  25. height:1000
  26. });
  27. var layer=new Kinetic.Layer();
  28. var flag=false;
  29. var imgArray=[];
  30. var lineArray=[];
  31. var tmpMoveImg=null;
  32. var loop=0;
  33. function  Pos(x,y){
  34. this.x=x;
  35. this.y=y;
  36. };
  37. function LineImage(img,line){
  38. this.img=img;
  39. this.line=line;
  40. };
  41. function NewImage(img,opsArray){
  42. this.img=img;
  43. this.opsArray=opsArray;
  44. };
  45. var imgA= new Image();
  46. imgA.onload=function(){
  47. var imgObjA= createImage(imgA,100,100,100,100)
  48. var array=new Array();
  49. var na=new  NewImage(imgObjA,array);
  50. imgArray.push(na);
  51. layer.add(imgObjA);
  52. stage.add(layer);
  53. }
  54. var imgB= new Image();
  55. imgB.onload=function(){
  56. var imgObjB= createImage(imgB,400,400,100,100)
  57. var array=new Array();
  58. var nb=new  NewImage(imgObjB,array);
  59. imgArray.push(nb);
  60. layer.add(imgObjB);
  61. stage.add(layer);
  62. }
  63. var imgC= new Image();
  64. imgC.onload=function(){
  65. var imgObjC= createImage(imgC,700,100,100,100)
  66. var array=new Array();
  67. var nc=new  NewImage(imgObjC,array);
  68. imgArray.push(nc);
  69. layer.add(imgObjC);
  70. stage.add(layer);
  71. }
  72. var rect=new Kinetic.Rect({
  73. x:0,
  74. y:0,
  75. width:1000,
  76. height:1000,
  77. fill:'white',
  78. storke:'red',
  79. storkeWidth:5
  80. });
  81. layer.add(rect);
  82. imgA.src='img/db.png';
  83. imgB.src='img/mj.png';
  84. imgC.src="img/kt1.png";
  85. rect.on('dblclick',function(){
  86. if(loop%2==0){
  87. flag=true;
  88. for(var i=0;i<imgArray.length;i++){
  89. imgArray[i].img.setDraggable(false);
  90. }
  91. }else{
  92. flag=false;
  93. for(var i=0;i<imgArray.length;i++){
  94. imgArray[i].img.setDraggable(true);
  95. imgArray[i].img.on('mouseover',function(){
  96. var p=new Pos(this.getX(),this.getY());
  97. tmpMoveImg=getImgByPos(p);
  98. })
  99. imgArray[i].img.on('dragmove',function(){
  100. for(var j=0;j<tmpMoveImg.opsArray.length;j++){
  101. var realPoints=[];
  102. calculateStartEndPos(tmpMoveImg.opsArray[j].img,this,realPoints);
  103. var line= createLine(realPoints);
  104. var oldLine=tmpMoveImg.opsArray[j].line;
  105. var p=new Pos(tmpMoveImg.opsArray[j].img.getX(),tmpMoveImg.opsArray[j].img.getY());
  106. var oppoImg= getImgByPos(p);
  107. replaceOppoLine(oppoImg,oldLine,line);
  108. layer.remove(tmpMoveImg.opsArray[j].line);
  109. tmpMoveImg.opsArray[j].line=line;
  110. layer.add(line);
  111. layer.draw();
  112. realPoints=[];
  113. }
  114. layer.draw();
  115. })
  116. }
  117. }
  118. loop++;
  119. for(var i=0;i<imgArray.length;i++){
  120. var innerFlag=false;
  121. var points=[];//标记性的点,为了获取img 使用
  122. var realPoints=[];//真正计算后合理的划线点
  123. imgArray[i].img.on('mousedown',function(){
  124. if(flag){
  125. var pos= stage.getMousePosition();
  126. points.push(this.getX());
  127. points.push(this.getY());
  128. innerFlag=true;
  129. }
  130. });
  131. imgArray[i].img.on('mouseup',function(){
  132. if(flag&&innerFlag){
  133. var pos= stage.getMousePosition();
  134. points.push(this.getX());
  135. points.push(this.getY());
  136. var p=new Pos(points[0],points[1]);
  137. var op=new Pos(points[2],points[3]);
  138. var opImg=getImgByPos(p);
  139. var owImg=getImgByPos(op);
  140. if(opImg!=owImg){
  141. calculateStartEndPos(opImg.img,owImg.img,realPoints);
  142. var line= createLine(realPoints);
  143. var opLine=new LineImage(opImg.img,line);
  144. var owLine=new LineImage(owImg.img,line);
  145. owImg.opsArray.push(opLine);
  146. opImg.opsArray.push(owLine);
  147. flag=false;
  148. innerFlag=false;
  149. points=[];
  150. realPoints=[];
  151. layer.add(line);
  152. layer.draw();
  153. }
  154. }
  155. });
  156. }
  157. })
  158. /**
  159. * 通过坐标获取Img对象
  160. */
  161. function getImgByPos(pos){
  162. for(var i=0;i<imgArray.length;i++){
  163. if(imgArray[i].img.getX()==pos.x&&imgArray[i].img.getY()==pos.y){
  164. return imgArray[i];
  165. }
  166. }
  167. }
  168. /**
  169. * 替换对方中line
  170. */
  171. function replaceOppoLine(imgObj,oldLine,newLine){
  172. for(var i=0;i<imgObj.opsArray.length;i++){
  173. if(imgObj.opsArray[i].line==oldLine){
  174. imgObj.opsArray[i].line=newLine;
  175. }
  176. }
  177. }
  178. /**
  179. 划线
  180. */
  181. function createLine(points){
  182. var line=new Kinetic.Line({
  183. points:points,
  184. stroke:'bule',
  185. strokeWidth:5,
  186. lineCap:'round',
  187. lineJoin:'round'
  188. });
  189. return line;
  190. }
  191. /**
  192. * 计算划线的开始坐标
  193. */
  194. function calculateStartEndPos(imgStart,imgEnd,realPoints){
  195. var realSx=0;
  196. var realSy=0;
  197. var realEx=0;
  198. var realEy=0;
  199. var sx=imgStart.getX();
  200. var sy=imgStart.getY();
  201. var swidth=imgStart.getWidth();
  202. var sheight=imgStart.getHeight();
  203. var ex=imgEnd.getX();
  204. var ey=imgEnd.getY();
  205. var ewidth=imgEnd.getWidth();
  206. var eheight=imgEnd.getHeight();
  207. var arrayx=calculateX(sx,swidth,ex,ewidth );
  208. var arrayy=calculateY(sy,sheight,ey,eheight );
  209. realPoints.push(arrayx[0]);
  210. realPoints.push(arrayy[0]);
  211. realPoints.push(arrayx[1]);
  212. realPoints.push(arrayy[1]);
  213. }
  214. /**
  215. 计算开始和结束节点x坐标
  216. */
  217. function calculateX(sx,swidth,ex,ewidth ){
  218. var arrayX=[];
  219. if(sx>ex){
  220. arrayX.push(sx);
  221. arrayX.push(ex+ewidth);
  222. }else if(sx==ex){
  223. arrayX.push(sx+(swidth/2));
  224. arrayX.push(sx+(ewidth/2));
  225. }else{
  226. arrayX.push(sx+swidth);
  227. arrayX.push(ex);
  228. }
  229. return  arrayX;
  230. }
  231. /**
  232. 计算开始和结束节点y坐标
  233. */
  234. function calculateY(sy,sheight,ey,eheight ){
  235. var arrayY=[];
  236. if(sy>ey){
  237. arrayY.push(sy+(sheight/2));
  238. arrayY.push(ey+(eheight/2));
  239. }else if(sy==ey){
  240. arrayY.push(sy+(sheight/2));
  241. arrayY.push(sy+(eheight/2));
  242. }else{
  243. arrayY.push(sy+(sheight/2));
  244. arrayY.push(ey+(eheight/2));
  245. }
  246. return  arrayY;
  247. }
  248. /**
  249. 画图
  250. */
  251. function createImage(img,x,y,width,height){
  252. var imgObj=new Kinetic.Image({
  253. x:x,
  254. y:y,
  255. width:width,
  256. height:height,
  257. draggable:true,
  258. image:img
  259. });
  260. imgObj.on("mouseover", function(){
  261. document.body.style.cursor = "pointer";
  262. });
  263. imgObj.on("mouseout", function(){
  264. document.body.style.cursor = "default";
  265. });
  266. return imgObj
  267. }
  268. });
  269. </script>
  270. </head>
  271. <body>
  272. <div id="container"></div>
  273. </body>
  274. </html>
  275. <img alt="" src="http://dl.iteye.com/upload/attachment/0070/8176/f9bb5503-b35b-3a45-abb1-0241a1495665.png">
  276. <img alt="" src="http://dl.iteye.com/upload/attachment/0070/8178/54c788d0-1395-3824-aea1-280b70b6f523.png">

效果如下

 

代码里还有一项基于extjs4 的实现和纯html5 canvas 的实现

基于html5二个div 连线的更多相关文章

  1. 基于Html5 Plus + Vue + Mui 移动App 开发(二)

    基于Html5 Plus + Vue + Mui 移动App 开发(二) 界面效果: 本页面采用Html5 Plus + Vue + Mui 开发移动界面,本页面实现: 1.下拉刷新.上拉获取更多功能 ...

  2. HT for Web基于HTML5的图像操作(二)

    上篇介绍了HT for Web采用HTML5 Canvas的getImageData和setImageData函数,通过颜色乘积实现的染色效果,本文将再次介绍另一种更为高效的实现方式,当然要实现的功能 ...

  3. 基于HTML5技术的电力3D监控应用(二)

    上篇介绍了我们电力项目的基本情况,我们选用HTML5技术还是顶着很大压力,毕竟HTML5技术性能行不行,浏览器兼容性会不会有问题,这些在项目选型阶段还是充满疑惑,项目做到现在终于快收尾了我们才敢松口气 ...

  4. 使用PhoneGap开发基于Html5应用二:第一个PhoneGap应用:百度

    上一篇博文使用PhoneGap开发基于Html5应用一:PhoneGap简单介绍 中我介绍了怎样从phonegap官网上下载源代码并启动第一个应用,今天我们把phonegap的应用略微改一下,让他实现 ...

  5. 基于 HTML5 WebGL 的发动机 3D 可视化系统

    前言     工业机械产品大多体积庞大.运输成本高,在参加行业展会或向海外客户销售时,如果没有实物展示,仅凭静态.简单的图片说明书介绍,无法让客户全面了解产品,不仅工作人员制作麻烦,客户看得也费力.如 ...

  6. 基于HTML5实现3D热图Heatmap应用

    Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. http://www.hightopo.c ...

  7. 基于HTML5 Canvas实现的图片马赛克模糊特效

    效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...

  8. 基于HTML5实现的Heatmap热图3D应用

    Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. 已有众多文章分享了生成Heatmap热图原 ...

  9. 基于HTML5技术的电力3D监控应用(三)

    继(一)和(二)之后不少,不少网友问我移动终端的使用问题,因为我们项目这次采用Android平板终端,所以我对这方面有点肤浅的研究,这篇分享些项目经验总结,希望对大家有所帮助. 电力3D项目去年底刚立 ...

随机推荐

  1. UIWebView半透明设置

    在项目中有时候需要弹出活动弹框,由于原生的样式会固定,所以考虑h5显示,这就需要webView的背景色半透明,如图: 让 UIWebView 背景透明需要以下设置

webView.backgroun ...

  2. chrome模拟慢速3G网络

    谷歌调试控制台中network中可以设置,add为自定义

  3. 【NOIP2017提高组模拟12.24】B

    题目 现在你有N个数,分别为A1,A2,-,AN,现在有M组询问需要你回答.每个询问将会给你一个L和R(L<=R),保证Max{Ai}-Min{Ai}<=R-L,你需要找出并输出最小的K( ...

  4. 【mysql】利用全文索引实现中文的快速查找

    现在我们数据库表中的记录大约在17万,每一条记录都有name字段,根据name做模糊匹配,效率非常低下. 表结构如下: create table T ( id int, name ) ); 总数据量如 ...

  5. 类型xxx 无法反序列化。缺乏对应的数据成员。

    WebApi——json返回多了 k_BackingField   产生原因: model类添加了    [System.Serializable] 返回json的时候会出现.

  6. 1222/2516. Kup

    题目描述 Description 首先你们得承认今天的题目很短很简洁... 然后,你们还得承认接下来这个题目的描述更加简洁!!! Task:给出一个N*N(1≤N≤2000)的矩阵,还给出一个整数K. ...

  7. 曙光浪潮IBM驱动

    https://pan.baidu.com/s/1lDrotg5jpdN_z0yOYyAo4w

  8. nginx展示文件目录

    1. 如何让nginx显示文件夹目录 vi /etc/nginx/conf.d/default.conf 添加如下内容: location / { root /data/www/file //指定实际 ...

  9. Node.js 几个重启工程的工具

    pm2, forever, nodemon, supervisor 均可在 npm 查找相关资料和用法. 线上工程推荐 pm2 开发推荐 supervisor

  10. How to Create a Basic Plugin 如何写一个基础的jQuery插件

    How to Create a Basic Plugin Sometimes you want to make a piece of functionality available throughou ...