我有一个用例,设计人员向我们提供 SVG,然后我们使用该 SVG 中的某些元素来定位动态创建的元素。
在下面的代码片段中,我尝试使用 getBoundingClientRect
将 rect#overlayTarget 与 div#overlay 重叠:它不考虑父元素的缩放,并且元素也不考虑重叠。
此问题的答案在这里不适用,因为它使用 element.offsetLeft
和 element.offsetTop
,它们不适用于 SVG:How to compute getBoundingClientRect() without considering transforms?
如何使#overlay 和#overlayTarget 重叠?
const target = document.querySelector("#overlayTarget");
const position = target.getBoundingClientRect();
const overlay = document.querySelector("#overlay");
overlay.style.top = `${position.y}px`;
overlay.style.left = `${position.x}px`;
overlay.style.width = `${position.width}px`;
overlay.style.height = `${position.height}px`;
#overlay {
position: absolute;
background: hotpink;
opacity: 0.3;
width: 100px;
height: 100px;
}
<div id="app" style="transform: scale(0.875);">
Test
<div id="overlay"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="1809" height="826" viewBox="0 0 809 826">
<g
id="Main_overview"
data-name="Main overview"
transform="translate(-49.5 -155)"
>
<g
id="overlayTarget"
data-name="DC-DC converter"
transform="translate(400 512)"
>
<rect
id="Rectangle_29"
data-name="Rectangle 29"
width="74"
height="74"
fill="none"
stroke="#47516c"
stroke-width="2"
/>
</g>
</g>
</svg>
</div>
最佳答案
如果您无法在转换后的元素之外设置覆盖元素,则此答案将有效,但仅适用于一些简单的转换:
- 翻译和
- 使用 > 0 的因子进行缩放
在这些情况下,边界框的 Angular 不会移出其上/左和下/右方向。旋转或倾斜,以及大多数 3D 变换都无法实现。
然后,您可以通过使用逆矩阵将 position
的 Angular 转换为 #app
元素的设置来计算叠加层的结果框值。 DOMPoint和 DOMMatrix接口(interface)对此有所帮助。
请务必记住,transform
设置隐式 position:relative
,因此 top
和 left
覆盖层的值与视口(viewport)无关。
const app = document.querySelector('#app');
const relative = app.getBoundingClientRect();
const target = document.querySelector("#overlayTarget");
const position = target.getBoundingClientRect();
const matrix = new DOMMatrix(app.style.transform).inverse();
const topleft = new DOMPoint(
position.x - relative.x,
position.y - relative.y
).matrixTransform(matrix);
const bottomright = new DOMPoint(
position.x - relative.x + position.width,
position.y - relative.y + position.height
).matrixTransform(matrix);
const overlay = document.querySelector("#overlay");
overlay.style.top = `${topleft.y}px`;
overlay.style.left = `${topleft.x}px`;
overlay.style.width = `${bottomright.x - topleft.x}px`;
overlay.style.height = `${bottomright.y - topleft.y}px`;
#overlay {
position: absolute;
background: hotpink;
opacity: 0.3;
width: 100px;
height: 100px;
}
<div id="app" style="transform: scale(0.875);">
Test
<div id="overlay"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="1809" height="826" viewBox="0 0 809 826">
<g
id="Main_overview"
data-name="Main overview"
transform="translate(-49.5 -155)"
>
<g
id="overlayTarget"
data-name="DC-DC converter"
transform="translate(400 512)"
>
<rect
id="Rectangle_29"
data-name="Rectangle 29"
width="74"
height="74"
fill="none"
stroke="#47516c"
stroke-width="2"
/>
</g>
</g>
</svg>
</div>
关于javascript - 如何在缩放的 svg 中计算 getBoundingClientRect()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64206235/