首页 > 解决方案 > 如何在一组方向上移动 SVG 中的线

问题描述

我有一个由 4 个线条形状组成的矩形。我希望能够通过拖动它的 4 个边之一来调整它的大小,但它需要保持矩形形状,我将尝试说明如下:

在此处输入图像描述

线条ab, bc, cd,da是单独的线条形状。在这个例子中,通过用鼠标拖动,我需要移动线条cd,但它需要与其他线条保持矩形形状(也需要对所有线条起作用,cd只是示例)。到目前为止,我有一个用于拖动线的代码:

function moveLine(previousCoo, x1, y1, x2, y2){ //following example above, x1 and y1 are point d and x2, y2 are point c
    if(document.getElementById('Line')){
        document.removeChild(document.getElementById('Line'));
    }
    var myLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
    myLine.setAttributeNS(null, "id", "Line");
    myLine.setAttributeNS(null, "x1", x1);
    myLine.setAttributeNS(null, "y1", y1);
    myLine.setAttributeNS(null, "x2", x2);
    myLine.setAttributeNS(null, "y2", y2);
    myLine.setAttributeNS(null, "stroke", "green");
    myLine.setAttributeNS(null, "stroke-width", 3);
    $(myLine).mousemove(function (e) {  //on mouse move, mousedown is already determined from another function
        var coo = getCoordinates(e.pageX, e.pageY); //function for getting current mouse coordinates
        var dCoo = [coo[0] - previousCoo[0], coo[1] - previousCoo[1]];   //calculate how much the mouse was moved
        x1 += dCoo[0];
        y1 += dCoo[1];
        x2 += dCoo[0];
        y2 += dCoo[1];
        moveLine(coo, x1, y1, x2, y2);
    }.bind(this));
    $(myLine).mouseup(function (e) {

        finish();

    }.bind(this));
    document.appendChild(myLine);
}

这仅适用于移动线,但我需要它仅沿上图所示的方向移动。我试着玩鼻窦、鼻窦和什么没用但没有用的东西。有人可以指出我正确的方向吗?谢谢!

标签: javascriptdomsvggeometry

解决方案


我正在使用 Robert Longson 的想法来旋转坐标系。

我会这样做:

矩形和线条围绕 [0,0] 点绘制,并且它们所在的组被旋转。这些线也有一个h水平线和v垂直线的类。或者,您可以检查是否 x1 == x2 用于垂直线或 y1 == y2 用于水平线,而不是分类。

当您拖动线条时,您会重置水平线的y1,属性和垂直线的,属性。y2x1x2

该功能oMousePosSVG正在检测 svg 画布上的鼠标位置。

let lines = Array.from(document.querySelectorAll("#greenLines line"));
let dragging = false;
let theclass =  "";
let theLine = null;
let m = {}


lines.forEach((l,i) =>{
  l.addEventListener("mousedown",()=>{
    dragging = i+1;
    l.style.stroke = "red"
    theclass = l.getAttribute("class")
    theLine = lines[dragging - 1];
  })
})

  svg.addEventListener("mousemove",(e)=>{
    if(dragging){
       m = oMousePosSVG(e)
       if(theclass == "h"){
       theLine.setAttributeNS(null,"y1",m.y);
       theLine.setAttributeNS(null,"y2",m.y);
       }
       if(theclass == "v"){
       theLine.setAttributeNS(null,"x1",m.x);
       theLine.setAttributeNS(null,"x2",m.x);
       }
  }
  })

  svg.addEventListener("mouseup",()=>{
     lines[dragging - 1].style.stroke = "green"; 
     dragging = false;
  })


function oMousePosSVG(e) {
      var p = svg.createSVGPoint();
      p.x = e.clientX;
      p.y = e.clientY;
      var ctm = svg.getScreenCTM().inverse();
      var p =  p.matrixTransform(ctm);
      return p;
}
svg{border:1px solid}
#greenLines line{stroke:green; stroke-width:5px;stroke-linecap:round}
<svg id="svg" viewBox="-100 -100 200 200" >
  <g transform="rotate(25)">
  <polygon id="poly" points="-50,-30 50,-30 50,30 -50,30 -50,30"/>
  <g id="greenLines">
    <line id="ab" class="h" x1="-50" y1="30"  x2="50" y2="30" />
    <line id="bc" class="v" x1="50" y1="30"  x2="50" y2="-30" />
    <line id="cd" class="h" x1="50" y1="-30" x2="-50" y2="-30"  />
    <line id="da" class="v" x1="-50" y1="-30"  x2="-50" y2="30"  /> 
  </g>
  </g>
</svg>


推荐阅读