基于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项目去年底刚立 ...
随机推荐
- poj1419 Graph Coloring 最大独立集(最大团)
最大独立集: 顶点集V中取 K个顶点,其两两间无连接. 最大团: 顶点集V中取 K个顶点,其两两间有边连接. 最大独立集=补图的最大团最大团=补图的最大独立集 #include<iostream ...
- Linux查看磁盘空间大小
1. Ubuntu 查看磁盘空间大小命令 df -h Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 命令格式: df -hl 显示格式为: 文件系统 容 ...
- Understand:高效代码静态分析神器详解(一) 转
之前用Windows系统,一直用source insight查看代码非常方便,但是年前换到mac下面,虽说很多东西都方便了,但是却没有了静态代码分析工具,很幸运,前段时间找到一款比source ins ...
- angularjs 结构的两种写法(2)
app.js里面 route.js 本项目中的路由写法,路由的意思是:对应的跳转页面路径,比如此处当路由是member.user-statisttic时,是会跳转到url:http://.../use ...
- 【leetcode】1230.Toss Strange Coins
题目如下: You have some coins. The i-th coin has a probability prob[i] of facing heads when tossed. Ret ...
- shell练习--PAT题目1005:继续(3n+1)猜想(全绿失败喜加一)
卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对 n=3 进行验证的时 ...
- spring boot 配置HTTPS
spring boot 版本是<version>1.5.8.RELEASE</version> 1.配置文件里,看下不要有空格=[不要有空格] 2.别名 =========== ...
- java-dockerfile
java环境dockefile FROM centos:7 MAINTAINER yon@taexa.com ENV JAVA_HOME /usr/local/jdk ENV JRE_HOME ${J ...
- SPOJ 913 Query on a tree II
spoj题面 Time limit 433 ms //spoj的时限都那么奇怪 Memory limit 1572864 kB //1.5个G,疯了 Code length Limit 15000 B ...
- JS获取URL指定的参数值
function GetUrlValue(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)( ...