我想在 SVG 中的文本周围放置一个矩形。我知道文本的高度(元素的font-size
属性)。text
但宽度取决于实际内容。使用getBBox()
或getComputedTextLength()
应该工作。但这仅在渲染后有效。
有没有办法以其他方式指定?例如定义相对于其他值的x
and属性?width
我在 SVG 规范中没有找到类似的东西。
确定文本结束的位置可能需要与渲染本身实现的基本代码路径大致相同 - 根据字体和样式等遍历每个字符的宽度......因为我不知道 SVG 标准定义了一种直接获取的方法这些信息没有进行实际的完整渲染,直到出现此类方法或被其他人报告,该方法应该是在进行实际渲染之前不可见地渲染。
您可以在隐藏层(z-index、不透明度和其他东西)或可见视口之外执行此操作,以在实验中效果最佳者为准。您只需要让浏览器进行渲染即可找出答案,因此您为此隐身渲染,然后使用getComputedTextLength()
可以使用canvas
with measureText()
:
// Get text width before rendering
const getTextWidth = (text, font) => {
const element = document.createElement('canvas');
const context = element.getContext('2d');
context.font = font;
return context.measureText(text).width;
}
// Demo
const font = '16px serif';
const text = 'My svg text';
const textWidth = getTextWidth(text, font);
document.body.innerHTML = `
<svg>
<text x="0" y="20" font="${font}">${text}</text>
<rect x="0" y="30" width="${textWidth}" height="4" fill="red" />
</svg>
`;
我知道这很旧,但有一些想法:
如果您可以选择等宽字体,您可以通过简单的常数乘以字形计数来了解您的宽度
如果您必须使用比例字体,则可以找到平均字形大小,像使用单空间一样进行数学运算,并留下足够的填充。text
或者,您可以使用元素textLength
属性填充填充。如果仔细选择常数,结果不会很令人不快。
编辑:因为 matanster 发现它是 hacky
getComputedTextLength()
并构建查找表。缺点是它不考虑字距调整,但如果您的缓存大小不是问题,您可以在此查找中附加字形对宽度。除此之外,还要找到一些方法来进行服务器端渲染:有没有办法使用 React 执行 SVG 图形的服务器端渲染?