基于html5的拖拽建站,基于html5 拖拽连线加强版实现

自动折线,自动判断起始点坐标,拖拽位置变换,大小拖拽,箭头指向等功能,这个版本稍微复杂一点,

还有个简单版本的实现http://zha-zi.iteye.com/blog/1586814 这个应该比较容易理解坐标换算不太多

body {

margin: 0px;

padding: 0px;

}

canvas {

border: 1px solid #9C9898;

}

Ext.onReady(function(){

/**

自动折叠连线算法

*/

var stage=new Kinetic.Stage({

container:'container',

width:1000,

height:1000

});

/**

箭头角度

*/

var arrowAngle=30;

/**

箭头半径

*/

var arrowRadius=5;

/**

箭头长度

*/

var arrowLenght=10;

/**

表示方向

*/

var E="E";

var W="W";

var S="S";

var N="N";

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;

};

/**

img 图像

lineArrow 带有箭头的line

flag 图像与箭头的指向关系

*/

function LineImage(img,lineArrow,flag){

this.img=img;

this.lineArrow=lineArrow;

this.flag=flag

};

function LineArrow(line,arrow){

this.line=line;

this.arrow=arrow;

};

function NewImage(img,opsArray,group){

this.img=img;

this.group=group;

this.opsArray=opsArray;

};

var imgA= new Image();

var imgObjA;

var groupA;

imgA.οnlοad=function(){

imgObjA= createImage(imgA,100,100,100,100)

var array=new Array();

groupA=new Kinetic.Group({

draggable:true

});

groupA.add(imgObjA);

layer.add(groupA);

addAnchor(groupA, 100, 100,"topLeft");

addAnchor(groupA, 200, 100,"topRight");

addAnchor(groupA, 200, 200,"bottomRight");

addAnchor(groupA, 100, 200,"bottomLeft");

var na=new NewImage(imgObjA,array,groupA);

imgArray.push(na);

stage.add(layer);

}

var imgB= new Image();

var imgObjB;

var groupB;

imgB.οnlοad=function(){

imgObjB= createImage(imgB,400,400,100,100)

var array=new Array();

groupB=new Kinetic.Group({

draggable:true

});

groupB.add(imgObjB);

layer.add(groupB);

addAnchor(groupB, 400, 400,"topLeft");

addAnchor(groupB, 500, 400,"topRight");

addAnchor(groupB, 500, 500,"bottomRight");

addAnchor(groupB, 400, 500,"bottomLeft");

var nb=new NewImage(imgObjB,array,groupB);

imgArray.push(nb);

stage.add(layer);

}

var imgC= new Image();

var imgObjC;

var groupC;

imgC.οnlοad=function(){

imgObjC= createImage(imgC,700,100,100,100)

var array=new Array();

groupC=new Kinetic.Group({

draggable:true

});

groupC.add(imgObjC);

layer.add(groupC);

addAnchor(groupC, 700, 100,"topLeft");

addAnchor(groupC, 800, 100,"topRight");

addAnchor(groupC, 800, 200,"bottomRight");

addAnchor(groupC, 700, 200,"bottomLeft");

var nc=new NewImage(imgObjC,array,groupC);

imgArray.push(nc);

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[i].group.setDraggable(false);

}

}else{

flag=false;

for(var i=0;i

imgArray[i].group.setDraggable(true);

imgArray[i].img.on('mouseover',function(){

var p=new Pos(this.getAbsolutePosition().x,this.getAbsolutePosition().y);

tmpMoveImg=getImgByPos(p);

});

imgArray[i].group.on('dragmove',function(){

for(var j=0;j

var realPoints=[];

if(tmpMoveImg.opsArray[j].flag){

calculateStartEndPos(tmpMoveImg.opsArray[j].img,this.children[0],realPoints);

}else{

calculateStartEndPos(this.children[0],tmpMoveImg.opsArray[j].img,realPoints);

}

tmpMoveImg.opsArray[j].lineArrow.line.setPoints(realPoints);

var arrowPoint= calculateArrowPointsByPoints(realPoints);

tmpMoveImg.opsArray[j].lineArrow.arrow.setPoints(arrowPoint);

layer.draw();

realPoints=[];

}

layer.draw();

});

imgArray[i].group.on('dragmove',function(){

for(var j=0;j

//lineArray[j].hide();

//moveLineToTarget(lineArray[j])

}

});

}

}

loop++;

for(var i=0;i

var innerFlag=false;

var points=[];//标记性的点,为了获取img 使用

var realPoints=[];//真正计算后合理的划线点

imgArray[i].img.on('mousedown',function(){

if(flag){

var pos= stage.getMousePosition();

points=[];

points.push(this.getAbsolutePosition().x);

points.push(this.getAbsolutePosition().y);

innerFlag=true;

}

});

imgArray[i].img.on('mouseup',function(){

if(flag&&innerFlag){

var pos= stage.getMousePosition();

points.push(this.getAbsolutePosition().x);

points.push(this.getAbsolutePosition().y);

//起始点

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 lineArrow= createLine(realPoints);

var opLine=new LineImage(opImg.img,lineArrow,true);

var owLine=new LineImage(owImg.img,lineArrow,false);

owImg.opsArray.push(opLine);

opImg.opsArray.push(owLine);

flag=false;

innerFlag=false;

points=[];

realPoints=[];

lineArray.push(lineArrow);

layer.add(lineArrow.line);

layer.add(lineArrow.arrow);

layer.draw();

bandEventToLine(lineArrow.line);

}

}

});

}

})

/**

* 通过坐标获取Img对象

*/

function getImgByPos(pos){

for(var i=0;i

if(imgArray[i].img.getAbsolutePosition().x==pos.x&&imgArray[i].img.getAbsolutePosition().y==pos.y){

return imgArray[i];

}

}

}

/**

* 替换对方中line

*/

function replaceOppoLine(imgObj,oldLine,newLine){

for(var i=0;i

if(imgObj.opsArray[i].line==oldLine){

imgObj.opsArray[i].line=newLine;

}

}

}

/**

* 计算划线的开始坐标

*/

function calculateStartEndPos(imgStart,imgEnd,realPoints){

var realSx=0;

var realSy=0;

var realEx=0;

var realEy=0;

var sx=imgStart.getAbsolutePosition().x;

var sy=imgStart.getAbsolutePosition().y;

var swidth=imgStart.getWidth();

var sheight=imgStart.getHeight();

var ex=imgEnd.getAbsolutePosition().x;

var ey=imgEnd.getAbsolutePosition().y;

var ewidth=imgEnd.getWidth();

var eheight=imgEnd.getHeight();

var array=calculateXY(sy,sheight,ey,eheight ,sx,swidth,ex,ewidth);

var crossArray=null;

if((array[0]!=array[2])&&(array[1]!=array[3])){

var crossArray= calculateCrossPoints(array,sy,sheight,ey,eheight ,sx,swidth,ex,ewidth);

}

realPoints.push(array[0]);

realPoints.push(array[1]);

if(crossArray!=null)

for(var i=0;i

realPoints.push(crossArray[i]);

}

realPoints.push(array[2]);

realPoints.push(array[3]);

}

/**

计算连线开始和结束坐标的位置

*/

function calculateXY(sy,sheight,ey,eheight,sx,swidth,ex,ewidth ){

var array=[];

if(sy==ey){

if(sx>ex){

array.push(sx);

array.push(sy+(sheight/2));

array.push(ex+ewidth);

array.push(sy+(eheight/2));

}else{

array.push(sx+swidth);

array.push(sy+(sheight/2));

array.push(ex);

array.push(sy+(eheight/2));

}

}else{

if(sy>ey&&(sy-ey>sheight)){

if(sx>ex){

if(sx-ex

array.push(sx);

array.push(sy+(sheight/2));

array.push(ex);

array.push(ey+eheight/2);

}else{

array.push(sx);

array.push(sy+(sheight/2));

array.push(ex+(ewidth/2));

array.push(ey+eheight);

}

}else if(sx==ex){

array.push(sx+(swidth/2));

array.push(sy);

array.push(ex+(ewidth/2));

array.push(ey+eheight);

}else{

if(ex-sx

array.push(sx);

array.push(sy+(sheight/2));

array.push(ex);

array.push(ey+eheight/2);

}else{

array.push(sx+swidth);

array.push(sy+(sheight/2));

array.push(ex+(ewidth/2));

array.push(ey+eheight);

}

}

}else if(syeheight)){

if(sx>ex){

if(sx-ex

array.push(sx);

array.push(sy+sheight/2);

array.push(ex);

array.push(ey+eheight/2);

}else{

array.push(sx+(swidth/2));

array.push(sy+sheight);

array.push(ex+ewidth);

array.push(ey+(eheight/2));

}

}else if(sx==ex){

array.push(sx+(swidth/2));

array.push(sy+sheight);

array.push(ex+(ewidth/2));

array.push(ey);

}else{

if(ex-sx

array.push(sx);

array.push(sy+sheight/2);

array.push(ex);

array.push(ey+eheight/2);

}else{

array.push(sx+(swidth/2));

array.push(sy+sheight);

array.push(ex);

array.push(ey+(eheight/2));

}

}

}else{

if((syey&&(sy-ey

array.push(sx+swidth/2);

array.push(sy);

array.push(ex+ewidth/2);

array.push(ey);

}

}

}

return array;

}

/**

计算折叠点的位置

*/

function calculateCrossPoints(array,sy,sheight,ey,eheight ,sx,swidth,ex,ewidth){

var pointsArray=[];

var x=array[0];

var y=array[1];

var x1=array[2];

var y1=array[3];

var f=false;

if((x-x1)>0&&(y-y1)>0){

f=true;

}

if((x1-x)>0&&(y1-y)>0){

f=true;

}

/**

y轴的多个折叠点

*/

if((sy>ey&&sy-ey<=sheight)||(sy

if(sy>ey&&sy-ey<=sheight){

pointsArray.push(x);

pointsArray.push(y1-sheight);

pointsArray.push(x1);

pointsArray.push(y1-sheight);

}else if(sy

pointsArray.push(x);

pointsArray.push(y-eheight);

pointsArray.push(x1);

pointsArray.push(y-eheight);

}

}else if((sx>ex&&sx-ex<=sheight/2)||(sx

/**

x轴的多个折点

*/

//x= sx-swidth/2

//y=y+sheight/2

if(sx-ex

pointsArray.push(sx-ewidth);

pointsArray.push(sy+sheight/2);

pointsArray.push(sx-ewidth);

pointsArray.push(ey+eheight/2);

}else if(ex-sx

pointsArray.push(ex-swidth);

pointsArray.push(sy+sheight/2);

pointsArray.push(ex-swidth);

pointsArray.push(ey+eheight/2);

}

}else{

/**

单个折叠点

*/

if(f){

if(x

pointsArray.push(x);

}else{

pointsArray.push(x1);

}

if(y

pointsArray.push(y1);

}else{

pointsArray.push(y);

}

}else{

if(x

pointsArray.push(x1);

}else{

pointsArray.push(x);

}

if(y

pointsArray.push(y1);

}else{

pointsArray.push(y);

}

}

}

return pointsArray;

}

function createImage(img,x,y,width,height){

var imgObj=new Kinetic.Image({

x:x,

y:y,

width:width,

height:height,

//draggable:true,

image:img,

name:"image",

});

imgObj.on("mouseover", function(){

document.body.style.cursor ="pointer";

});

imgObj.on("mouseout", function(){

document.body.style.cursor ="default";

});

return imgObj

}

/**

根据points 节点数组划线

*/

function createLine(points){

var line=new Kinetic.Line({

points:points,

stroke:'green',

strokeWidth:2,

lineCap:'round',

lineJoin:'round'

});

var lenght=points.length;

var x=points[lenght-4];

var y=points[lenght-3];

var x1=points[lenght-2];

var y1=points[lenght-1];

var arrow=createArrow(calculateArrowPosition(x1,y1,calculateArrowAspect(x,y,x1,y1)),"black");

var la =new LineArrow(line,arrow);

return la;

}

function bandEventToLine(line){

line.saveData();

line.on("mouseover", function(){

document.body.style.cursor ="pointer";

});

line.on("mouseout", function(){

document.body.style.cursor ="default";

});

}

/**

通过line计算 arrow 的points 数组

*/

function calculateArrowPointsByLine(line){

var points=line.getPoints();

var lenght=points.length;

var x=points[lenght-4];

var y=points[lenght-3];

var x1=points[lenght-2];

var y1=points[lenght-1];

return calculateArrowPosition(x1,y1,calculateArrowAspect(x,y,x1,y1));

}

function calculateArrowPointsByPoints(points){

var lenght=points.length;

var x=points[lenght-4];

var y=points[lenght-3];

var x1=points[lenght-2];

var y1=points[lenght-1];

return calculateArrowPosition(x1,y1,calculateArrowAspect(x,y,x1,y1));

}

/**

计算箭头朝向

*/

function calculateArrowAspect(x,y,x1,y1){

if(x==x1){

if(y>y1){

return N;

}else{

return S;

}

}else if(y==y1){

if(x>x1){

return W;

}else{

return E;

}

}

}

/**

计算箭头具体位置

*/

function calculateArrowPosition(x,y,aspect){

var points=[];

switch(aspect){

case N:

points.push(x);

points.push(y);

points.push(x-arrowRadius);

points.push(y+arrowLenght);

points.push(x+arrowRadius);

points.push(y+arrowLenght);

break;

case S:

points.push(x);

points.push(y);

points.push(x-arrowRadius);

points.push(y-arrowLenght);

points.push(x+arrowRadius);

points.push(y-arrowLenght);

break;

case E:

points.push(x);

points.push(y);

points.push(x-arrowLenght);

points.push(y+arrowRadius);

points.push(x-arrowLenght);

points.push(y-arrowRadius);

break;

case W:

points.push(x);

points.push(y);

points.push(x+arrowLenght);

points.push(y+arrowRadius);

points.push(x+arrowLenght);

points.push(y-arrowRadius);

break;

}

return points;

}

function createArrow(points,fill){

var arrow=new Kinetic.Polygon({

points: points,

fill: fill,

stroke:"black",

strokeWidth: 1

});

return arrow;

}

function addAnchor(group,x,y,name){

var stage=group.getStage();

var layer=group.getLayer();

var anchor=new Kinetic.Circle({

x:x,

y:y,

stroke:'#666',

fill:'green',

radius:1,

name:name,

draggable:true

});

anchor.on('dragmove',function(){

update(group, this);

layer.draw();

});

anchor.on('dragend',function(){

group.setDraggable(true);

layer.draw();

});

anchor.on('mousedown touchstar',function(){

group.setDraggable(false);

//this.moveToTop();

});

anchor.on('mouseover',function(){

var layer = this.getLayer();

document.body.style.cursor ="pointer";

this.setRadius(3);

layer.draw();

});

anchor.on('mouseout',function(){

var layer = this.getLayer();

document.body.style.cursor ="default";

this.setRadius(1);

layer.draw();

});

group.add(anchor);

}

function update(group,activeAnchor){

var topLeft=group.get(".topLeft")[0];

var topRight=group.get(".topRight")[0];

var bottomLeft=group.get(".bottomLeft")[0];

var bottomRight=group.get(".bottomRight")[0];

var image=group.children[0];

switch(activeAnchor.getName()){

case"topLeft":

topRight.attrs.y = activeAnchor.attrs.y;

bottomLeft.attrs.x = activeAnchor.attrs.x;

break;

case"topRight":

topLeft.attrs.y = activeAnchor.attrs.y;

bottomRight.attrs.x = activeAnchor.attrs.x;

break;

case"bottomRight":

bottomLeft.attrs.y = activeAnchor.attrs.y;

topRight.attrs.x = activeAnchor.attrs.x;

break;

case"bottomLeft":

bottomRight.attrs.y = activeAnchor.attrs.y;

topLeft.attrs.x = activeAnchor.attrs.x;

break;

}

image.setPosition(topLeft.attrs.x, topLeft.attrs.y);

image.setSize(topRight.attrs.x - topLeft.attrs.x, bottomLeft.attrs.y - topLeft.attrs.y);

}

});

48018009_9.png

48018009_10.png

13ed4f2c-8be4-36ee-bd91-8f0ed8e9c1cc.png

1c6f6b4c-bfaf-3459-81cb-d8cbc892ba0f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值