Javascript SVG 调整大小适用于 chrome 但不适用于 safari

Javascript SVG resize work on chrome but not safari

我有一些代码旨在调整 SVG 上文本的大小,使其适合特定大小。

它似乎在 chrome 上工作正常,但在任何其他浏览器上都没有(我试过 IE11 和 Safari)。

这是代码

<html>
  <body>
  <style>
@import url('https://fonts.googleapis.com/css?family=Sonsie+One');
text {
  font-family: "Sonsie One";
}
svg {
  background: #43C6AC;
}
</style>
<svg version="1.2" viewBox="0 0 600 400" width="600" height="400" xmlns="http://www.w3.org/2000/svg">
  <text id="t1" style="fill: white;" x="50%" y="50%" text-anchor="middle">Test</text>
</svg>
<script>
function resize() { 
    var width = 350,
      height = 80;
    var textNode = document.getElementById("t1");
    for (var k = 1; k < 60; k++) {
      textNode.setAttribute("font-size", k)
      var bb = textNode.getBBox()
      if (bb.width > width || bb.height > height)
        break;
    }
}
window.onload = resize;      
</script>
</body>
</html>

这是 运行 url:http://hiven.com/momo.html

谁能告诉我哪里出错了?在 chrome 中,它会将文本大小调整为 350px,但在其他情况下则不会。

我发现这个问题是由字体加载的时间引起的。 (我在 Epiphany WEB 上测试过,它有 WebKit 渲染引擎作为 Safari。)

由于window.onload是在字体加载完成前调用的,resize方法在后备字体样式下工作,因此bbox获取的文字大小不正确。

所以这个问题是通过等待字体加载完成来解决的。但是WebKit似乎不支持document.fonts.onloadingenddocument.fonts.load字体加载的api(或者对这种情况没有影响)。

所以我用canvas这样的元素做了等待系统(但我认为这不是最好的。)

<html>
  <body>
        <style>
    @import url('https://fonts.googleapis.com/css?family=Sonsie+One');
    text {
        font-family: "Sonsie One";
    }
    svg {
        background: #43C6AC;
    }
        </style>
        <svg viewBox="0 0 600 400" width="600" height="400">
            <text id="t1" style="fill: white;" x="50%" y="50%" 
            text-anchor="middle">Test some long text here</text>
        </svg>
        <script>
function resize() {
    var width = 350,
      height = 80;
    var textNode = document.getElementById("t1");
    for (var k = 1; k < 60; k++) {
      textNode.setAttribute("font-size", k)
      var bb = textNode.getBBox()
      if (bb.width > width || bb.height > height)
        break;
    }
}

//window.onload = resize;
//waiting font loading
{
    var cnt = 0;
    function tryResize(){
        if(!ready() && cnt < 30){
            setTimeout(tryResize, 100);
            cnt++;
        }else{
            resize();
        }
    }
    //check the state of font loading
    var c1 = document.createElement("canvas");
    var c2 = c1.cloneNode(false);
    var ctx1 = c1.getContext("2d");
    var ctx2 = c2.getContext("2d");
    //set target font and fallback font 
    ctx1.font = "normal 30px 'Sonsie One', serif";
    ctx2.font = "normal 30px serif";
    var text = "this is test text.";  
    function ready(){
        //compare text length.
        //when the target font loading is complted, 
        //the legth of text will be changed
        return ctx1.measureText(text).width != ctx2.measureText(text).width;
    }
    //start waiting
    tryResize();
}
        </script>
    </body>
</html>

演示:http://jsdo.it/defghi1977/ueFO