使用 React 在 SVG 中居中文本

Center text in SVG with React

首先,是的,我进行了搜索并且看到了许多其他可用的答案。但他们对我不起作用。

我希望能够使我的 SVG 中的文本居中。

因为我必须能够将它放在左侧、中间或右侧(水平和垂直方向),所以我尝试变得有点通用并以编程方式计算 x 和 y。

这是一个例子:https://codesandbox.io/s/ll6ppwkyq7

您可以在结果中看到文本没有垂直居中。

红色方框是文字的边框。

黑框是我应该居中的框。

元素的x坐标与文本位置坐标的关系与元素的 y 坐标和 bottom 位置。其实是颠倒的。

这是因为在垂直方向上,文本位于元素的底部,y 坐标从上到下,而水平坐标与文本的方向相同。

这在使用您正在使用的 GetBBbox() 方法时很容易看到。例如,当在 x 和 y 的坐标 0 处添加文本元素时,您会看到 getBBbox 会给您一个 x = 0 但一个负的 y。

console.log(document.getElementById('testbbox').getBBox());
<svg id="testbbox"><text x=0 y=0>test</text></svg>

因此,使文本居中的计算方式已经有所不同。你现在拥有的是:

outerRect.x - ((outerRect.width - innerRect.width) / 2)

之所以可行,是因为您假设内部矩形从 0 开始,但事实并非如此。您的边界框垂直为负。所以完整的公式应该是这样的:

outerRect.x - innerRect.x - ((outerRect.width - innerRect.width) / 2)

在你的例子中是:

x - bboxx + ( (width - boxWidth) / 2)

其中 bboxxgetBBox()

你可以使用基线,但是 dytspan 上,这使得计算有点复杂,不确定是不是好方法。由于无论如何 getBBox 在计算中都考虑了基线,所以它并不是真正必要的。

另外,如果你看这里,文本的基线应该是显性基线,而不是对齐基线:https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline

看看它是如何影响边界框的,尤其是y坐标:

console.log(document.getElementById('central').getBBox());
console.log(document.getElementById('top').getBBox());
<svg id="central">
<text y=10 dominant-baseline="central" >test</text>
</svg>
<svg id="top">
<text y=10 dominant-baseline="top" >test</text>
</svg>

查看最终结果: https://codesandbox.io/s/52wl31l8zn