基于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项目去年底刚立 ...
随机推荐
- SpringMVC POJO入参过程分析
SpringMVC确定目标方法POJO类型的入参过程 1.确认一个key: (1).若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POJO类名第一个字母的小写 ...
- @ResponseStatus注解作用
@ResponseStatus注解有两种用法,一种是加载自定义异常类上,一种是加在目标方法中 这里我们说一下加在目标方法上的这种情况,注解中有两个参数,value属性设置异常的状态码,reaseon是 ...
- ZROI 19.08.01 生成函数方法
写在前面:由于我数学基础不好,加上缺乏生成函数知识,所以这一下午我都处在掉线和非掉线的叠加态.而且我写\(\LaTeX\)很慢,所以笔记相当混乱而且不全面.说白了就是我太菜了听不懂. 1.一般生成函数 ...
- 阅读之SQL优化
一.性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句, ...
- springCloud——Eureka、Ribbon理解
一. 服务注册中心.服务提供者.服务消费者 如何通信? 客户端: 应用主类中配置@EnableDiscoveryClient application.properties中配置defaultZone指 ...
- 12. ClustrixDB 为容错和可用性分配磁盘空间
集群必须包含足够的空闲磁盘空间,以便从节点或区域故障中自动恢复.要计算在发生故障后仍然允许ClustrixDB完全重新保护数据的情况下可以使用的最大磁盘空间量,可以使用以下公式: 最大磁盘利用率% = ...
- Zabbix4.x安装部署
zabbix监控的重要性就不用再赘述了.直接上干货. 1.环境背景: Linux:CentOS 7.x, Database:MySQL zabbix server 和 zabbix mysql 安装在 ...
- maven项目解决pom.xml头部 http://maven.apache.org/xsd/maven-4.0.0.xsd报错的问题
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qq_36611526/article/d ...
- java大文件上传
上次遇到这样一个问题,客户上传高清视频(1G以上)的时候上传失败. 一开始以为是session过期或者文件大小受系统限制,导致的错误.查看了系统的配置文件没有看到文件大小限制,web.xml中sees ...
- #418 Div2 Problem B An express train to reveries (构造 || 全排列序列特性)
题目链接:http://codeforces.com/contest/814/problem/B 题意 : 有一个给出两个含有 n 个数的序列 a 和 b, 这两个序列和(1~n)的其中一个全排列序列 ...