SVG Text bounding box different from browser when using @ font-face?

I am trying to position an SVG text element according to the width and height of the text, getting a bounding box using the getBBox () method.

If the text uses the websafe font, this works well in different browsers, but if the text is designed using the @ font-face font and a custom webfont, then the width of the text returns incorrectly in Firefox (Mac) and Safari (iOS). It works great in both Safari (Mac) and Chrome (Mac).

If the gray square has the same width as the text, it works in this browser.

Does anyone have an idea on how to get the correct width of the bounding box text in all browsers?

+4
source share
2 answers

The browser calculates the BBox before it finishes loading / applying @font-face , try ...

 onreadystatechange="if(document.readyState == "complete"){init()}" 

document.readyState fires in three states: loading (when the page loads), interactive (when it has finished parsing, but still loading resouces), and complete (when the browser is really finished), so you just add a condition to execute init() when document.readyState complete.

+2
source

Today I ran into a similar problem. Duopixel is correct that getBBox () may return a metric, which may be unexpected because the external font has not yet been loaded, and a standard font is used instead.

The problem with WebKit (tested in the Chrome 24.0.1312.52 and 26.0.1389.0 canaries) is that the browser delays loading the external font until it is used efficiently anywhere on the page. Therefore, even if you expect that onreadystatechange will become "complete", you are not guaranteed that font metrics will be displayed when you call getBBox () - you can still display the text in style with an external font, inserting it into the document and immediately calling getBBox () on it (my case).

My workaround instead of calling mySVGInitCode () directly:

 $("body").append( $("<div/>") .attr("class", "force-external-font-loading") .attr("style", "font-family: \"xkcd\";visibility:hidden;position:absolute") .text("x") ); setTimeout(function(){ mySVGInitCode() }, 100); // 100ms is just arbitrary waiting time which should be sufficient for fetching the external font on a fast network, anyone has a better solution? 

As you can see, I dynamically insert an absolutely positioned stylized piece of text to force external fonts to be loaded (visibility: hidden is important here instead of showing: none). Then I wait a while before I execute my SVG code, which can potentially do something, and then immediately request metrics.

+1
source

Source: https://habr.com/ru/post/1435317/


All Articles