svg图形之间连线

843 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

1、前言

接前文,素材有了,素材可移动了,接下来就是素材之间的连线了。要求:点击图形--》拖动鼠标--》松开鼠标连线。这个操作跟图形移动的操作有重叠的部分,比如都有点击图形的步骤。这时候首先判断 点击图形 是要连线还是移动图形。

2、如何判断操作意图

一般而言,当光标靠近图形时点击,这时候肯定是要连线。当鼠标完全悬浮在图形内,这时候的点击事件肯定是为了移动图片。想到就做。

2.1 首先监视鼠标的位置

注:circles图形的DOM对象,该图形是一个同心圆 当鼠标离图形的中心足够近时,将光标换成 move 样式。 当鼠标远离图形的中心时,将光标切换成 crosshair 样式

        //鼠标移动事件,当鼠标移动到图形距离圆心时,点击可以拖动图形,当鼠标在边缘移动时,点击可以连线
        document.onmousemove = function(ev){
            var currentX = ev.offsetX;//鼠标移动中的当前位置  X  
            var currentY = ev.offsetY;//鼠标移动中的当前位置  Y 
            var clientRect = circles.getBoundingClientRect();//图形的坐标
            var distanceX = Math.abs(currentX-clientRect.x);
            var distanceY = Math.abs(currentY-clientRect.y);
            if(distanceX<5 && distanceY<5){//距离圆心小于 5
                circles.style.cursor= "move";
            }else{
                circles.style.cursor= "crosshair";
            }
        }

2.2 连线 Or 移动

注:container 是画布的 DOM 对象

    var statas = false;//同心圆可操作状态
    var statas2 = false;//线可操作状态
    //点击同心圆
    circles.onmousedown = function(e){
            statas = true;//点击同心圆时,状态设置为true,代表可移动、可连线
            var beginX = e.offsetX;//鼠标的起始坐标 X 
            var beginY = e.offsetY;//鼠标的起始坐标 Y
            console.log("开始的坐标" +beginX+"=="+beginY);
        }
    var count = 0;
    
    container.onmousedown=function(e){
            var beginX = e.offsetX;//鼠标的起始坐标 X 
            var beginY = e.offsetY;//鼠标的起始坐标 Y
            if(circles.style.cursor == "crosshair" && statas){//选中同心圆且光标是 crosshair
                statas = false;
                statas2 = true;//线的状态
                var attrs = {
                    "stroke-miterlimit" : "10",
                    d : "",
                    "id" : "moveline"+count
                };
                var line2 = resetSvg('path', attrs);
                lines.appendChild(line2);
                var moveline = document.getElementById("moveline"+count);
            }
            container.onmousemove=function(ev){
                if(statas){
                    var currentX = ev.offsetX-98;//鼠标移动中的当前位置  X  98是同心圆首位置X
                    var currentY = ev.offsetY-46;//鼠标移动中的当前位置  Y  46是同心圆首位置X
                    //记录X、Y坐标的变化
                    circles.setAttribute("transform","translate("+currentX+","+currentY+")");
                    return;
                }
                if(statas2){
                    var moveX = ev.offsetX;
                    var moveY = ev.offsetY;
                    var move ='M'+beginX+' '+beginY+' L'+moveX+' '+moveY;
                    moveline.setAttribute('d',move);
                }
            }
            container.onmouseup=function(ev){
                statas = false;
                statas1 = false;
                statas2 = false;
                count++;
            }
        }