Javascript SVG调整chrome的工作,但不是safari

时间:2017-03-02 22:24:55

标签: javascript svg cross-browser webfonts

我已经获得了一些代码,用于调整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>

这是在网址上运行:http://hiven.com/momo.html

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

1 个答案:

答案 0 :(得分:1)

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

由于在完成字体加载之前调用了window.onloadresize方法在后备字体样式下工作,因此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