javascript - 如何在缩放的 svg 中计算 getBoundingClientRect()?

标签 javascript svg

我有一个用例,设计人员向我们提供 SVG,然后我们使用该 SVG 中的某些元素来定位动态创建的元素。

在下面的代码片段中,我尝试使用 getBoundingClientRect 将 rect#overlayTarget 与 div#overlay 重叠:它不考虑父元素的缩放,并且元素也不考虑重叠。

此问题的答案在这里不适用,因为它使用 element.offsetLeftelement.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 元素的设置来计算叠加层的结果框值。 DOMPointDOMMatrix接口(interface)对此有所帮助。

请务必记住,transform 设置隐式 position:relative,因此 topleft覆盖层的值与视口(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/

相关文章:

javascript - Skype JavaScript 插件格式

javascript - Instafeed 不返回方形照片

由于另一个干扰函数,Javascript 函数无法正常工作

javascript - 使用 ember-cp-validations 验证可选电子邮件

wordpress - 在古腾堡的图像 block 中上传 SVG 图像

javascript - 如何在屏幕中间居中 div。或者,如果使用 flexbox,如何禁用外部 div 可点击性但保留内部 div 可点击性?

html - SVG 高度元素不是动态的?

javascript - Angular2 xlink :href Issues

javascript - d3 防止在上下文菜单上触发鼠标移出

javascript - 如何使用 D3 检测散点图中的重叠点?