如何获得SVG文本元素的紧密边界框

时间:2017-05-25 10:54:51

标签: javascript svg text web-frontend

通常为了获得SVG中任何元素的边界框,我们使用getBoundingClientRect()或getBBox()分别给出top,bottom,left,right,width,height或x,y,width,height。但是当文本被旋转时,这些值不足以得到元素的紧密边界框,因为由这些值形成的框将具有水平和垂直边缘,而不是与文本平行。如何为旋转的文本选择紧密边界框,如下图所示。 (Chrome Inspect元素选择器突出显示了该文本。)

3 个答案:

答案 0 :(得分:4)

我认为如果你想要4个点,你可能需要在边界框上使用与元素相同的变换对它们进行变换。如果它只是用于显示,只需将相同的变换应用于已显示的边界框。我想如果你想要4分,那就有点复杂了,但可能会有更简单的方法。

无论如何这可能是有用的。

我们抓住文本的边界框。 我们在元素上抓取矩阵(在本例中为旋转)。 然后我们将它应用于我们从边界框收集的所有点。 我添加了一些代码,只是为了在点上创建圆圈,以突出显示它。



var text = document.querySelector('text');
var svg = document.querySelector('svg')


function getTransformedPts( el ) {
  var m = el.getCTM();
  var bb = el.getBBox();
  var tpts = [
    matrixXY(m,bb.x,bb.y),
    matrixXY(m,bb.x+bb.width,bb.y),
    matrixXY(m,bb.x+bb.width,bb.y+bb.height),
    matrixXY(m,bb.x,bb.y+bb.height) ]
  
  return tpts;
}

function matrixXY(m,x,y) {
            return { x: x * m.a + y * m.c + m.e, y: x * m.b + y * m.d + m.f };
}

var pts = getTransformedPts( text );

for( pt in pts ) {
  var c = document.createElementNS("http://www.w3.org/2000/svg","circle");
  c.setAttribute('cx', pts[pt].x);
  c.setAttribute('cy', pts[pt].y);
  c.setAttribute('r',3)
  svg.append(c)
}

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="800" height="800">
<text x="50" y="50" transform="rotate(10)" font-size="30">testing rotated text box points</text>
</svg>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果使用<text>获取getBBox()元素的边界框,则它通常是未旋转的边界框。这是因为getBBox()在计算要返回的值时不包含元素transform

例如,请看下面的示例。比较文本BBox和其父组元素的BBox。

&#13;
&#13;
var text = document.getElementById("text");
var b = text.getBBox();
console.log("text bbox="+[b.x,b.y,b.width,b.height].join(' '));

var group = document.getElementById("group");
var b = group.getBBox();
console.log("group bbox="+[b.x,b.y,b.width,b.height].join(' '));
&#13;
<svg width="300" height="300">

  <g id ="group">
    <text id="text" x="150" y="150" text-anchor="middle" font-size="30"
          transform="rotate(45,150,150)">ROTATED</text>
  </g>

</svg>
&#13;
&#13;
&#13;

答案 2 :(得分:-1)

没有直接的方法来实现这一目标。但您可以尝试以下解决方案。

How to get rotated svg text bounds in javascript programmatically