基于html5二个div 连线


因为要实现拖拽连线研究了一下基于extjs 和html5的不同实现方法
extjs底层的画图引擎是svg 不知道在html5大潮即将袭来的前夕一贯走在技术前沿的extjs开发团队没有自己封装基于html5的画图引擎,而是选择了svg 。
下边是花了不到一天的时间实现的任意点连线和拖动功能,代码没有优化,稍微乱了点
如果单纯应用canvas进行画图,拖拽是非常麻烦的,我们往往要基于第三方的画图类库,这里实现是基于kineticjs
为了测试方便我使用了双击事件控制拖动还是划线 。
代码
- <!DOCTYPE HTML>
- <html>
- <head>
- <style>
- body {
- margin: 0px;
- padding: 0px;
- }
- canvas {
- border: 1px solid #9C9898;
- }
- </style>
- <script type="text/javascript" src="ext/bootstrap.js"></script>
- <!-- ENDLIBS -->
- <script type="text/javascript" src="ext/ext-all-debug.js"></script>
- <script src="js/kinetic-v3.10.2.min.js"></script>
- <script>
- Ext.onReady(function(){
- /**
- 自动判断顶点连线算法
- */
- var stage=new Kinetic.Stage({
- container:'container',
- width:1000,
- height:1000
- });
- var layer=new Kinetic.Layer();
- var flag=false;
- var imgArray=[];
- var lineArray=[];
- var tmpMoveImg=null;
- var loop=0;
- function Pos(x,y){
- this.x=x;
- this.y=y;
- };
- function LineImage(img,line){
- this.img=img;
- this.line=line;
- };
- function NewImage(img,opsArray){
- this.img=img;
- this.opsArray=opsArray;
- };
- var imgA= new Image();
- imgA.onload=function(){
- var imgObjA= createImage(imgA,100,100,100,100)
- var array=new Array();
- var na=new NewImage(imgObjA,array);
- imgArray.push(na);
- layer.add(imgObjA);
- stage.add(layer);
- }
- var imgB= new Image();
- imgB.onload=function(){
- var imgObjB= createImage(imgB,400,400,100,100)
- var array=new Array();
- var nb=new NewImage(imgObjB,array);
- imgArray.push(nb);
- layer.add(imgObjB);
- stage.add(layer);
- }
- var imgC= new Image();
- imgC.onload=function(){
- var imgObjC= createImage(imgC,700,100,100,100)
- var array=new Array();
- var nc=new NewImage(imgObjC,array);
- imgArray.push(nc);
- layer.add(imgObjC);
- stage.add(layer);
- }
- var rect=new Kinetic.Rect({
- x:0,
- y:0,
- width:1000,
- height:1000,
- fill:'white',
- storke:'red',
- storkeWidth:5
- });
- layer.add(rect);
- imgA.src='img/db.png';
- imgB.src='img/mj.png';
- imgC.src="img/kt1.png";
- rect.on('dblclick',function(){
- if(loop%2==0){
- flag=true;
- for(var i=0;i<imgArray.length;i++){
- imgArray[i].img.setDraggable(false);
- }
- }else{
- flag=false;
- for(var i=0;i<imgArray.length;i++){
- imgArray[i].img.setDraggable(true);
- imgArray[i].img.on('mouseover',function(){
- var p=new Pos(this.getX(),this.getY());
- tmpMoveImg=getImgByPos(p);
- })
- imgArray[i].img.on('dragmove',function(){
- for(var j=0;j<tmpMoveImg.opsArray.length;j++){
- var realPoints=[];
- calculateStartEndPos(tmpMoveImg.opsArray[j].img,this,realPoints);
- var line= createLine(realPoints);
- var oldLine=tmpMoveImg.opsArray[j].line;
- var p=new Pos(tmpMoveImg.opsArray[j].img.getX(),tmpMoveImg.opsArray[j].img.getY());
- var oppoImg= getImgByPos(p);
- replaceOppoLine(oppoImg,oldLine,line);
- layer.remove(tmpMoveImg.opsArray[j].line);
- tmpMoveImg.opsArray[j].line=line;
- layer.add(line);
- layer.draw();
- realPoints=[];
- }
- layer.draw();
- })
- }
- }
- loop++;
- for(var i=0;i<imgArray.length;i++){
- var innerFlag=false;
- var points=[];//标记性的点,为了获取img 使用
- var realPoints=[];//真正计算后合理的划线点
- imgArray[i].img.on('mousedown',function(){
- if(flag){
- var pos= stage.getMousePosition();
- points.push(this.getX());
- points.push(this.getY());
- innerFlag=true;
- }
- });
- imgArray[i].img.on('mouseup',function(){
- if(flag&&innerFlag){
- var pos= stage.getMousePosition();
- points.push(this.getX());
- points.push(this.getY());
- var p=new Pos(points[0],points[1]);
- var op=new Pos(points[2],points[3]);
- var opImg=getImgByPos(p);
- var owImg=getImgByPos(op);
- if(opImg!=owImg){
- calculateStartEndPos(opImg.img,owImg.img,realPoints);
- var line= createLine(realPoints);
- var opLine=new LineImage(opImg.img,line);
- var owLine=new LineImage(owImg.img,line);
- owImg.opsArray.push(opLine);
- opImg.opsArray.push(owLine);
- flag=false;
- innerFlag=false;
- points=[];
- realPoints=[];
- layer.add(line);
- layer.draw();
- }
- }
- });
- }
- })
- /**
- * 通过坐标获取Img对象
- */
- function getImgByPos(pos){
- for(var i=0;i<imgArray.length;i++){
- if(imgArray[i].img.getX()==pos.x&&imgArray[i].img.getY()==pos.y){
- return imgArray[i];
- }
- }
- }
- /**
- * 替换对方中line
- */
- function replaceOppoLine(imgObj,oldLine,newLine){
- for(var i=0;i<imgObj.opsArray.length;i++){
- if(imgObj.opsArray[i].line==oldLine){
- imgObj.opsArray[i].line=newLine;
- }
- }
- }
- /**
- 划线
- */
- function createLine(points){
- var line=new Kinetic.Line({
- points:points,
- stroke:'bule',
- strokeWidth:5,
- lineCap:'round',
- lineJoin:'round'
- });
- return line;
- }
- /**
- * 计算划线的开始坐标
- */
- function calculateStartEndPos(imgStart,imgEnd,realPoints){
- var realSx=0;
- var realSy=0;
- var realEx=0;
- var realEy=0;
- var sx=imgStart.getX();
- var sy=imgStart.getY();
- var swidth=imgStart.getWidth();
- var sheight=imgStart.getHeight();
- var ex=imgEnd.getX();
- var ey=imgEnd.getY();
- var ewidth=imgEnd.getWidth();
- var eheight=imgEnd.getHeight();
- var arrayx=calculateX(sx,swidth,ex,ewidth );
- var arrayy=calculateY(sy,sheight,ey,eheight );
- realPoints.push(arrayx[0]);
- realPoints.push(arrayy[0]);
- realPoints.push(arrayx[1]);
- realPoints.push(arrayy[1]);
- }
- /**
- 计算开始和结束节点x坐标
- */
- function calculateX(sx,swidth,ex,ewidth ){
- var arrayX=[];
- if(sx>ex){
- arrayX.push(sx);
- arrayX.push(ex+ewidth);
- }else if(sx==ex){
- arrayX.push(sx+(swidth/2));
- arrayX.push(sx+(ewidth/2));
- }else{
- arrayX.push(sx+swidth);
- arrayX.push(ex);
- }
- return arrayX;
- }
- /**
- 计算开始和结束节点y坐标
- */
- function calculateY(sy,sheight,ey,eheight ){
- var arrayY=[];
- if(sy>ey){
- arrayY.push(sy+(sheight/2));
- arrayY.push(ey+(eheight/2));
- }else if(sy==ey){
- arrayY.push(sy+(sheight/2));
- arrayY.push(sy+(eheight/2));
- }else{
- arrayY.push(sy+(sheight/2));
- arrayY.push(ey+(eheight/2));
- }
- return arrayY;
- }
- /**
- 画图
- */
- function createImage(img,x,y,width,height){
- var imgObj=new Kinetic.Image({
- x:x,
- y:y,
- width:width,
- height:height,
- draggable:true,
- image:img
- });
- imgObj.on("mouseover", function(){
- document.body.style.cursor = "pointer";
- });
- imgObj.on("mouseout", function(){
- document.body.style.cursor = "default";
- });
- return imgObj
- }
- });
- </script>
- </head>
- <body>
- <div id="container"></div>
- </body>
- </html>
- <img alt="" src="http://dl.iteye.com/upload/attachment/0070/8176/f9bb5503-b35b-3a45-abb1-0241a1495665.png">
- <img alt="" src="http://dl.iteye.com/upload/attachment/0070/8178/54c788d0-1395-3824-aea1-280b70b6f523.png">
效果如下

代码里还有一项基于extjs4 的实现和纯html5 canvas 的实现
基于html5二个div 连线的更多相关文章
- 基于Html5 Plus + Vue + Mui 移动App 开发(二)
基于Html5 Plus + Vue + Mui 移动App 开发(二) 界面效果: 本页面采用Html5 Plus + Vue + Mui 开发移动界面,本页面实现: 1.下拉刷新.上拉获取更多功能 ...
- HT for Web基于HTML5的图像操作(二)
上篇介绍了HT for Web采用HTML5 Canvas的getImageData和setImageData函数,通过颜色乘积实现的染色效果,本文将再次介绍另一种更为高效的实现方式,当然要实现的功能 ...
- 基于HTML5技术的电力3D监控应用(二)
上篇介绍了我们电力项目的基本情况,我们选用HTML5技术还是顶着很大压力,毕竟HTML5技术性能行不行,浏览器兼容性会不会有问题,这些在项目选型阶段还是充满疑惑,项目做到现在终于快收尾了我们才敢松口气 ...
- 使用PhoneGap开发基于Html5应用二:第一个PhoneGap应用:百度
上一篇博文使用PhoneGap开发基于Html5应用一:PhoneGap简单介绍 中我介绍了怎样从phonegap官网上下载源代码并启动第一个应用,今天我们把phonegap的应用略微改一下,让他实现 ...
- 基于 HTML5 WebGL 的发动机 3D 可视化系统
前言 工业机械产品大多体积庞大.运输成本高,在参加行业展会或向海外客户销售时,如果没有实物展示,仅凭静态.简单的图片说明书介绍,无法让客户全面了解产品,不仅工作人员制作麻烦,客户看得也费力.如 ...
- 基于HTML5实现3D热图Heatmap应用
Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. http://www.hightopo.c ...
- 基于HTML5 Canvas实现的图片马赛克模糊特效
效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...
- 基于HTML5实现的Heatmap热图3D应用
Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. 已有众多文章分享了生成Heatmap热图原 ...
- 基于HTML5技术的电力3D监控应用(三)
继(一)和(二)之后不少,不少网友问我移动终端的使用问题,因为我们项目这次采用Android平板终端,所以我对这方面有点肤浅的研究,这篇分享些项目经验总结,希望对大家有所帮助. 电力3D项目去年底刚立 ...
随机推荐
- Python核心技术与实战——十四|Python中装饰器的使用
我在以前的帖子里讲了装饰器的用法,这里我们来具体讲一讲Python中的装饰器,这里,我们从前面讲的函数,闭包为切入点,引出装饰器的概念.表达和基本使用方法.其次,我们结合一些实际工程中的例子,以便能再 ...
- DevExpress WinForms v19.1新版亮点:Spreadsheet/Sunburst控件功能增强
行业领先的.NET界面控件DevExpress v19.1终于正式发布,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WinForms v19.1中新增的一些控 ...
- webview默认是不开启localstorage的
.setDomStorageEnabled(true);// 打开本地缓存提供JS调用,至关重要 转载 https://blog.csdn.net/xhf_123/article/details/77 ...
- Linux系统中的硬件问题如何排查?(4)
Linux系统中的硬件问题如何排查?(4) 2013-03-27 10:32 核子可乐译 51CTO.com 字号:T | T 在Linux系统中,对于硬件故障问题的排查可能是计算机管理领域最棘手的工 ...
- return和exit以及C语言递归函数
return 在主函数main()中,return整个函数退出,在子函数中return,只退出子函数. exit exit无论在函数什么位置退出整个函数 递归函数 #include <stdio ...
- 【NOIP2016提高组day2】愤怒的小鸟
分析 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0, 0) 处,每次Kiana可以用它向第一象限发射一只红色的小鸟, 小鸟们的飞行轨迹均 ...
- 记第一次正式线上笔试(Tencent——正式考-技术研发类-综合-2018实习生招聘)
选择题做的跟傻逼一样,不多说了..大学只打了ACM还不是计算机科班出身的我,连好多名词都不认识..... 三道编程题很简单,下面给出三道题的大致题意以及题解. 1.给出n和m,满足(2m)可以整除n. ...
- Java word 内容读取
1.添加依赖关系(网上好多帖子没有写依赖,害我找半天) <dependency> <groupId>org.apache.poi</groupId& ...
- ssh复制公钥成功后仍需输入密码
1,网上说权限问题 登录流程: 被登录机器的文件权限: //用户权限 chmod 700 /home/username //.ssh文件夹权限 chmod 700 ~/.ssh/ // ~/.ssh/ ...
- ROM和RAM的内存详细说明
1.首先是ROM 的读取是需要提前两个地址的读取,所以要想读取0地址的数据,你需要给地址是2 2.关于宽度,深度的计算 假设我们要存取如下取模的数据,该模的设置口语描述为:这是显示的2个字节,其中一个 ...