我在网页上有各种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。
谢谢。
答案 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>