繁体   English   中英

Svg绘制两个矩形之间的连接线

[英]Svg draw connection line between two rectangles

我目前正在使用SVGjavascript编写图编辑器。

我遇到了关于矩形之间连接的问题。 我找到了很多资源来绘制圆圈之间的连接,但没有关于矩形的连接。

所以现在我得到的是,我可以通过用鼠标拖动线来绘制两个矩形之间的连接线,但是连接显示在它们内部,因为我从矩形的中点计算连接。

正如你在下面的图片中看到的那样,我给自己做了一些想法,但我没有完成最后一步。

我只想绘制标记为红色的线条。

我的问题的示例图片:我想绘制红线

后来我想拖动矩形,行应该更新,但现在我只需要计算这一行。

有人得到了一个很好的建议吗?

假设你有两个rects,你知道它们的中心( cx1cy1 )和( cx2cy2 )。 您还可以将宽度和高度除以2 (即从中心到两侧的距离):( w1h1 )和( w2h2 )。

它们之间的距离是:

var dx = cx2 - cx1;
var dy = cy2 - cy1;

然后,您可以使用以下公式计算两个rects的交点:

var p1 = getIntersection(dx, dy, cx1, cy1, w1, h1);
var p2 = getIntersection(-dx, -dy, cx2, cy2, w2, h2);

getIntersection是:

function getIntersection(dx, dy, cx, cy, w, h) {
  if (Math.abs(dy / dx) < h / w) {
    // Hit vertical edge of box1
    return [cx + (dx > 0 ? w : -w), cy + dy * w / Math.abs(dx)];
   } else {
    // Hit horizontal edge of box1
    return [cx + dx * h / Math.abs(dy), cy + (dy > 0 ? h : -h)];
    }
};

这是一个例子:

 var rect1 = document.getElementById('rect1'); var rect2 = document.getElementById('rect2'); var cxn = document.getElementById('connection'); updateConnection(); function updateConnection() { // Top left coordinates var x1 = parseFloat(rect1.getAttributeNS(null, 'x')); var y1 = parseFloat(rect1.getAttributeNS(null, 'y')); var x2 = parseFloat(rect2.getAttributeNS(null, 'x')); var y2 = parseFloat(rect2.getAttributeNS(null, 'y')); // Half widths and half heights var w1 = parseFloat(rect1.getAttributeNS(null, 'width')) / 2; var h1 = parseFloat(rect1.getAttributeNS(null, 'height')) / 2; var w2 = parseFloat(rect2.getAttributeNS(null, 'width')) / 2; var h2 = parseFloat(rect2.getAttributeNS(null, 'height')) / 2; // Center coordinates var cx1 = x1 + w1; var cy1 = y1 + h1; var cx2 = x2 + w2; var cy2 = y2 + h2; // Distance between centers var dx = cx2 - cx1; var dy = cy2 - cy1; var p1 = getIntersection(dx, dy, cx1, cy1, w1, h1); var p2 = getIntersection(-dx, -dy, cx2, cy2, w2, h2); cxn.setAttributeNS(null, 'x1', p1[0]); cxn.setAttributeNS(null, 'y1', p1[1]); cxn.setAttributeNS(null, 'x2', p2[0]); cxn.setAttributeNS(null, 'y2', p2[1]); } function getIntersection(dx, dy, cx, cy, w, h) { if (Math.abs(dy / dx) < h / w) { // Hit vertical edge of box1 return [cx + (dx > 0 ? w : -w), cy + dy * w / Math.abs(dx)]; } else { // Hit horizontal edge of box1 return [cx + dx * h / Math.abs(dy), cy + (dy > 0 ? h : -h)]; } }; function makeDraggable(evt) { var svg = evt.target; svg.addEventListener('mousedown', startDrag); svg.addEventListener('mousemove', drag); svg.addEventListener('mouseup', endDrag); function getMousePosition(evt) { var CTM = svg.getScreenCTM(); return { x: (evt.clientX - CTM.e) / CTM.a, y: (evt.clientY - CTM.f) / CTM.d }; } var selectedElement, offset; function startDrag(evt) { if (evt.target.classList.contains('draggable')) { selectedElement = evt.target; offset = getMousePosition(evt); offset.x -= parseFloat(selectedElement.getAttributeNS(null, "x")); offset.y -= parseFloat(selectedElement.getAttributeNS(null, "y")); } } function drag(evt) { if (selectedElement) { var coord = getMousePosition(evt); selectedElement.setAttributeNS(null, "x", coord.x - offset.x); selectedElement.setAttributeNS(null, "y", coord.y - offset.y); updateConnection(); } } function endDrag(evt) { selectedElement = null; } } 
 .static { cursor: not-allowed; } .draggable { cursor: move; fill: #007bff; fill-opacity: 0.1; stroke: #007bff; stroke-width: 0.2; } #connection { stroke-width: 0.1; stroke: red; } 
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20" onload="makeDraggable(evt)" width="400" height="200"> <rect id="rect1" class="draggable" x="4" y="5" width="4" height="3"/> <rect id="rect2" class="draggable" x="18" y="5" width="3" height="5"/> <line id="connection" /> </svg> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM