获取元素的边界框来计算其变换

Phr*_*ogz 28 javascript svg

鉴于此SVG:

<svg xmlns="http://www.w3.org/2000/svg">
  <rect width="50" height="50"
        transform="translate(75,75) rotate(45) translate(-25,-25)" />
  <script>
    var bb = document.querySelector('rect').getBBox();
    console.log([bb.x,bb,y,bb.width,bb.height]);
  </script>
</svg>?
Run Code Online (Sandbox Code Playgroud)

结果输出是[0, 0, 50, 50].
期望的结果是[39.645,39.645,70.711,70.711].

可视版本:http://jsfiddle.net/2wpju/7/

计算元素的边界框相对于其父元素的最简单,最有效的方法是什么?


下面是我到目前为止提出的最佳答案,但有两个问题:

  1. 对于可以更好地处理的事情,似乎做了很多工作
  2. 本演示所示,它不一定是最小边界框(注意上圆),因为旋转的轴对齐边界框的轴对齐边界框总是会增加尺寸.

 

// Calculate the bounding box of an element with respect to its parent element
function transformedBoundingBox(el){
  var bb  = el.getBBox(),
      svg = el.ownerSVGElement,
      m   = el.getTransformToElement(el.parentNode);

  // Create an array of all four points for the original bounding box
  var pts = [
    svg.createSVGPoint(), svg.createSVGPoint(),
    svg.createSVGPoint(), svg.createSVGPoint()
  ];
  pts[0].x=bb.x;          pts[0].y=bb.y;
  pts[1].x=bb.x+bb.width; pts[1].y=bb.y;
  pts[2].x=bb.x+bb.width; pts[2].y=bb.y+bb.height;
  pts[3].x=bb.x;          pts[3].y=bb.y+bb.height;

  // Transform each into the space of the parent,
  // and calculate the min/max points from that.    
  var xMin=Infinity,xMax=-Infinity,yMin=Infinity,yMax=-Infinity;
  pts.forEach(function(pt){
    pt = pt.matrixTransform(m);
    xMin = Math.min(xMin,pt.x);
    xMax = Math.max(xMax,pt.x);
    yMin = Math.min(yMin,pt.y);
    yMax = Math.max(yMax,pt.y);
  });

  // Update the bounding box with the new values
  bb.x = xMin; bb.width  = xMax-xMin;
  bb.y = yMin; bb.height = yMax-yMin;
  return bb;
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*nen 1

一种方法是制作一套拉斐尔套装并获得 bb。或者将所有元素包装在 g 内并获取 g 的 bb ,我认为 g 应该是最快的。