D3 如何在变换缩放/平移时保持元素大小相同

D3 How to keep element same size while transform scale / translate

这个例子说明了我的问题:https://bl.ocks.org/feketegy/ce9ab2efa9439f3c59c381f567522dd3

我在一个组元素中有几个路径,我想 pan/zoom 除了蓝色矩形路径之外的这些元素,它在另一个组元素中。

缩放和平移是通过将 transform="translate(0,0) scale(1) 应用到最外面的组元素然后捕获缩放增量并将其应用到 same-size 组元素以保持其相同大小来完成的。

这是可行的,但是应该保持相同大小的蓝色矩形位置被弄乱了,我想保持它与其他路径的相对位置相同。

呈现的 html 结构如下所示:

<svg width="100%" height="100%">
  <g class="outer-group" transform="translate(0,0)scale(1)">
    <path d="M100,100 L140,140 L200,250 L100,250 Z" fill="#cccccc" stroke="#8191A2" stroke-width="2px"></path>
    <path d="M400,100 L450,100 L450,250 L400,250 Z" fill="#cccccc" stroke="#8191A2" stroke-width="2px"></path>

    <g class="same-size-position" transform="translate(300,250)">
      <g class="same-size" transform="scale(1)">
        <path d="M0,0 L50,0 L50,50 L0,50 Z" fill="#0000ff"></path>
      </g>
    </g>
  </g>
</svg>

我试图获取 same-size-position 组的 X/Y 位置,并从 outer-group 的翻译 x/y 创建一个增量,但那没有好像不行。

清理高中几何书上的灰尘后,我找到了解决方案。

您需要获取要保持相同大小的元素的边界框,并计算其上的矩阵转换,如下所示:

const zoomDelta = 1 / d3.event.transform.k;

const sameSizeElem = d3.select('.same-size');
const bbox = sameSizeElem.node().getBBox();

const cx = bbox.x + (bbox.width / 2);
const cy = bbox.y + (bbox.height / 2);
const zx = cx - zoomDelta * cx;
const zy = cy - zoomDelta * cy;

sameSizeElem
  .attr('transform', 'matrix(' + zoomDelta + ', 0, 0, ' + zoomDelta + ', ' + zx + ', ' + zy + ')');

矩阵变换会保持元素的相对位置,大小不变,其他元素pan/zoom。