我希望能够计算SVG中文本(或跨度)元素占用的实际高度。
现在,我通过计算对象边界框的高度来实现这一点,但是它采用了字体字形的高度,因此我放在元素中的任何文本都具有相同的高度,如下例所示:
var minA = document.getElementById('min-a'),
capA = document.getElementById('cap-a'),
minAHeight = document.getElementById('min-a-height'),
capAHeight = document.getElementById('cap-a-height')
;
minAHeight.innerHTML = minA.getBBox().height;
capAHeight.innerHTML = capA.getBBox().height;
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 80">
<text id="min-a" x="20" y ="20">a</text>
<text id="cap-a" x="20" y ="50">Â</text>
<text id="min-a-height" x="70" y ="20"></text>
<text id="cap-a-height" x="70" y ="50"></text>
<svg>
如何计算每个元素的实际高度?
答案 0 :(得分:1)
对于svg中的文本,您可以根据需要手动设置字体大小
<svg:text #t
[attr.x]="xoffset"
[attr.y]="yoffset"
font-family="Courier"
[attr.font-size]="fontsize">
{{bottom_text.toUpperCase()}}
</svg:text>
这将为您的svg元素提供一个静态大小的字体。您还可以选择使用浏览器开发工具在实际元素上“检查元素”。在选择中显示所选元素的宽度和高度。 (例如,参见图片)这种“悬停在”高度将包括与元素相关联的任何填充,但是检查元素上列出的属性它还应该包含仅字体高度“font-size” < / p>
答案 1 :(得分:1)
@Fuzzyma走在正确的轨道上。您想使用OpenType.js并在浏览器中加载字体。
// These two match whatever you are doing in your code
const text = 'Hello'
const fontSize = 20
// Load font - I find ttf work better than woff (has extra data for other calculations if needed)
opentype.load(`/path/to/font.ttf`, (err, font) => {
// Actual dimensions of the text
const bb = font.getPath(text, 0, 0, fontSize)
})
这将为您提供真正的边界框,可满足您的需求。如果您确实需要使用它来了解文本上的屏幕位置,那么它可能会更具挑战性。
它的要点是你需要匹配基线。该字体包含ascender / descender(font.tables.hhea.asscender
,font.tables.hhea.descender
),一旦转换为em(font.tables.head.unitsPerEm * fontSize
),总计字体大小。
有了这个,你需要浏览字体的每个字形并获得yMax
,yMin
,xMin
和xMax
。使用ascender / descender和Y coords来确定你的新bb离“假”边界框(DOM返回的边界框)有多远。左边和右边更容易,除了一些奇怪的字体,其字母可以超出其邻居(边缘情况)。
在浏览器的基础上添加每个浏览器的垂直偏移...这可以通过获取SVG文本元素的y
属性(即-5)来提取 - 然后取你的字体大小,除以这个y
的一半和一个,你有浏览器使用的垂直偏移量(在我们的例子中为5)。每个浏览器都不同,但y
坐标反映了这一点。
答案 2 :(得分:0)
为此,您需要加载并解析字体文件,并使用存储在其中的字形来计算bouding框。 在服务器上,您可以使用opentype.js或fontkit加载字体并获取某些文本的边界框。
但是在客户端上,您需要自己解析字体文件。对于svg字体来说这很容易,但是当你处理二进制格式(例如truetype)时会变得更难
但是当你设法做到这一点时,你可以绘制glypgs的路径并使用浏览器getBBox()
来计算你想要的边界框。
这就是理论 - 但我的猜测是,比编写自己的字体文件解析器更容易解决这个问题。
如果有人知道,请随时修改!
答案 3 :(得分:0)
不确定这是否能解决您的问题,但我能够使用画布 measureText
方法计算单个字母的尺寸:
function getLetterSize(letter) {
const ctx = document.createElement("canvas").getContext("2d");
ctx.font = "25px sans-serif";
const dim = ctx.measureText(letter);
return {
width: dim.actualBoundingBoxRight + dim.actualBoundingBoxLeft,
height: dim.actualBoundingBoxAscent + dim.actualBoundingBoxDescent
};
}