offsetWidth,使用加载的字体时 SVG 宽度不正确

offsetWidth, SVG widths incorrect when using a loaded font

编辑 - 最初认为这只是一个 SVG 问题,但似乎适用范围更广。

我试图在 SVG 中绘制一些文本,然后在其周围放置一个矩形,并在 SnapSVG 的右侧填充。这适用于任何网络安全字体。但是,当我从 google 导入字体时,.getBBox() returns 宽度错误。 SO 的网络片段似乎没有复制问题,所以我在此处输入了代码,但要查看实际问题,您需要转到下面的代码笔。

var testsvg = Snap('#test')
testsvg.rect(0,0,400,400).attr({})
var pretext=testsvg.text(100,50,'I am the very model of').attr({fill:'white','font-family':"Asap"})
var text=testsvg.text(100,100,'I am the very model of').attr({fill:'white','font-family':"Asap"})
console.log(text.getBBox().width)
var boundrect=testsvg.rect(100,100-text.getBBox().height,text.getBBox().width+10,text.getBBox().height).attr({stroke:'white',fill:'none'})
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<style>
 @import url('https://fonts.googleapis.com/css?family=Asap');
</style>

<svg id='test' height='400' width='400'></svg>

这是代码笔:https://codepen.io/austinclemens/pen/WKZayE

您会注意到矩形的宽度应该是文本宽度 + 10,但它最终没有完全包围框。如果将文本更改为 Arial,它将立即生效。此外,如果您将文本更改为 Arial,然后再改回 Asap,Asap 会突然起作用。我在 Safari、Chrome 和 Firefox 中遇到了这个错误。在执行 JS 之前添加 window.onload() 似乎无济于事,使用任意等待也无济于事。

所以我怀疑这与字体加载有关。我想也许我可以通过 'initializing' 字体来修复它,可以说首先做一个不同的文本对象,但这没有帮助。我可以使用 HTML 解决方案,但在我的实际应用程序中,这会非常麻烦,所以我希望尽可能只使用 Snap。我实际上也不认为这是一个 snap 问题。查看 snap 的 getbbox 函数,它使用 this.node.getClientRects() 作为文本,returns 这里的宽度错误。

根据 LGSon 的推荐 post,我使用 fontfaceobserver 通过加载带有承诺的字体来解决此问题:https://github.com/bramstein/fontfaceobserver