簡體   English   中英

如何獲得 SVG 文本的實際高度(不是邊界框高度)

[英]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.asscenderfont.tables.hhea.descender ),一旦轉換為 em ( font.tables.head.unitsPerEm * fontSize ),它們的總和font.tables.hhea.descender字體大小。

有了這個,您就需要遍歷字體的每個字形並獲得yMaxyMinxMinxMax 使用上升/下降和 Y 坐標來確定你的新 bb 離“假”邊界框(DOM 返回的那個)有多遠。 左邊和右邊更容易,除了一些奇怪的字體,這些字體的字母可以超出他們的鄰居(邊緣情況)。

在瀏覽器之上添加一個每個瀏覽器的垂直偏移量......這可以通過獲取 SVG 文本元素的y屬性(即 -5)來提取 - 然后你取你的字體大小,除以一半,然后取這個y和您擁有瀏覽器使用的垂直偏移量(在我們的示例中為 5)。 每個瀏覽器都不同,但y坐標反映了這一點。

為此,您需要加載並解析一個字體文件並使用存儲在其中的字形來計算 bouding 框。 在服務器上,你會使用opentype.jsfontkit加載的字體,並得到一些文本的邊框。

但是在客戶端上,您需要自己解析字體文件。 這對於 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM