【问题标题】:Javascript SVG resize work on chrome but not safariJavascript SVG 调整大小适用于 chrome 但不是 safari
【发布时间】:2017-03-02 22:24:55
【问题描述】:

我有一些代码旨在调整 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,但在其他情况下则不会。

【问题讨论】:

  • 在 Chrome、Firefox、Opera 中运行正常。当字体为 Sonsie One 时,IE 不起作用,但在其他情况下可以正常工作。 (无法在 Safari 中测试)

标签: javascript svg cross-browser webfonts


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-04
    • 2010-09-18
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 2014-10-24
    相关资源
    最近更新 更多