svg:找到矩形顶点的x,y坐标

时间:2019-04-10 05:58:30

标签: javascript svg rect vertices

我在网页上有各种svg矩形,在该网页上以以下形式应用了转换:

    transform="translate(418 258) rotate(-45.2033 15 18) scale(2.5 2.5)"

应用变换后,我需要获取每个矩形的4个顶点的x,y坐标。

这是一个代码示例:

<g transform="translate(418 258) rotate(-45.25 15 18) scale(2.5 2.5)">
  <rect id="box" x="0" y="0" width="31" height="37" style="fill:none;stroke:rgb(102, 102, 102);stroke-width:1.5px;">
  </rect>
</g>

我已经在纯js中尝试了以下公式:

x' = x * cos(angle) + y * sin(angle)
y' = -x * sin(angle) + y * cos(angle)

但是结果与各种浏览器中的svg显示略有不同。

我猜这可以使用js / svg原语来完成,但是我不知道如何,也没有找到任何代码示例。也许在变换后将rects更改为路径会达到目的...

最后但并非最不重要的是,我使用的是jQuery而不是d3。

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以读取transform属性并将其转换为矩阵。 然后,对于矩形的四个角中的每个角,可以使用该矩阵来计算变换后的角位置。

请参阅以下演示。

此演示假定存在一个id"box"的元素,并且您关心的变换只是父<g>元素上的变换。如果您的情况比这更复杂,那么您将需要对该代码做更多的工作。

// Get a reference to the "box" rect element
var box = document.getElementById("box");
// Get its x, y, width and height
var bx = box.x.baseVal.value;
var by = box.y.baseVal.value;
var bw = box.width.baseVal.value;
var bh = box.height.baseVal.value;

// Get the box's parent element (the <g>)
var parentGroup = box.parentNode;
// Read the transform attribute and convert it to a transform matrix object
var transformMatrix = parentGroup.transform.baseVal.consolidate().matrix;

// For each of the rectangle's four corners, use the transform matrix to calculate its new coordinates
console.log("point 1 = ", doPoint(bx, by));
console.log("point 2 = ", doPoint(bx + bw, by));
console.log("point 3 = ", doPoint(bx + bw, by + bh));
console.log("point 4 = ", doPoint(bx, by + bh));



function doPoint(x, y)
{
  // We need a reference to the <svg> element for the next step
  var svg = box.ownerSVGElement;
  // Create an SVGPoint object with the correct x and y values
  var pt = svg.createSVGPoint();
  pt.x = x;
  pt.y = y;
  // Use the "matrixTransform()" method on SVGPoint to apply the transform matrix to the coordinate values
  pt = pt.matrixTransform(transformMatrix);
  // Return the updated x and y values
  return {x: pt.x, y: pt.y};
}
<svg>
  <g transform="translate(418 258) rotate(-45.25 15 18) scale(2.5 2.5)">
    <rect id="box" x="0" y="0" width="31" height="37" style="fill:none;stroke:rgb(102, 102, 102);stroke-width:1.5px;">
    </rect>
  </g>
</svg>