[英]How can I get the actual height of a SVG text (not the bounding box height)
我希望能夠計算 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>
如何計算每個元素的實際高度?
@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)
})
這將為您提供真正的邊界框,這可能足以滿足您的需求。 如果您確實需要使用它來了解文本上的屏幕位置,這是可能的,但它更具挑戰性。
它的要點是您需要匹配基線。 字體包含font.tables.hhea.asscender
/降序( font.tables.hhea.asscender
、 font.tables.hhea.descender
),一旦轉換為 em ( font.tables.head.unitsPerEm * fontSize
),它們的總和font.tables.hhea.descender
字體大小。
有了這個,您就需要遍歷字體的每個字形並獲得yMax
、 yMin
、 xMin
和xMax
。 使用上升/下降和 Y 坐標來確定你的新 bb 離“假”邊界框(DOM 返回的那個)有多遠。 左邊和右邊更容易,除了一些奇怪的字體,這些字體的字母可以超出他們的鄰居(邊緣情況)。
在瀏覽器之上添加一個每個瀏覽器的垂直偏移量......這可以通過獲取 SVG 文本元素的y
屬性(即 -5)來提取 - 然后你取你的字體大小,除以一半,然后取這個y
和您擁有瀏覽器使用的垂直偏移量(在我們的示例中為 5)。 每個瀏覽器都不同,但y
坐標反映了這一點。
為此,您需要加載並解析一個字體文件並使用存儲在其中的字形來計算 bouding 框。 在服務器上,你會使用opentype.js或fontkit加載的字體,並得到一些文本的邊框。
但是在客戶端上,您需要自己解析字體文件。 這對於 svg 字體來說很容易,但是當您處理二進制格式(例如 truetype)時會變得更難。
但是當您設法這樣做時,您可以繪制 glypgs 的路徑並使用瀏覽器getBBox()
來計算您想要的邊界框。
好吧,這就是理論 - 但我的猜測是,解決這個問題比編寫自己的字體文件解析器更容易。
當有人知道時,請隨時編輯!
不確定這是否能解決您的問題,但我能夠使用畫布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
};
}
對於 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”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.