【问题标题】:Strange viewbox font sizing behaviour inside CanvasCanvas 中奇怪的视图框字体大小调整行为
【发布时间】:2018-12-05 16:09:32
【问题描述】:

https://jsfiddle.net/diegojsrw/od12s9b4/14/

c.font = "100vh sans-serif";
c.fillStyle = "white";
c.fillText(fps.toFixed(0), w/2, 0);

最初,文本的高度看起来不错。

但是,当我调整窗口大小时,文本不会一起调整大小。文本不断地绘制在画布上(使用requestAnimationFrame)。

只有当我切换到另一个选项卡然后再切换回此选项卡时,才会重新调整文本大小。

有什么线索吗?

【问题讨论】:

    标签: html5-canvas requestanimationframe viewport-units


    【解决方案1】:

    您正面临一个 webkit 错误。最新的 Chrome 和 Safari 都受到关注。

    在 Canvas2D API 中,应在设置时计算相对单位/值,并且该计算值将被保存和使用。

    这意味着您的相对 100vw 值将被计算为其以绝对 px 为单位的对应值。

    这是建议始终使用画布 API 中的绝对单位的原因之一(其中包括舍入调整等)。

    但是如果你真的想使用这个单元,那么你必须在它每次改变时都设置它,这样你就可以盲目地进入你的循环,在调用fillText()之前再次设置ctx.font,但是为了表演,我建议您使用 脏标志,该标志会在窗口的 resize 事件中引发,并且仅在引发此标志时更新 ctx.font 属性。

    但这仅适用于遵循规范的浏览器...

    我不知道 webkit 浏览器何时会计算这个值,因为即使将 font 属性重置为其他值也不行,甚至将其设置为其他值(例如在 20vh 和 21vh 之间切换)也不行……

    所以我现在能看到的唯一解决方法是自己计算这个值。对于视口大小,这并不难(innerWidth / (100 / vw_val)),但即使对于其他相对单位,您也可以直接在画布上设置此 fontSize 并在画布上调用getComputedStyle()

    let dirtySize = true; // this is our resize flag
    const ctx = canvas.getContext('2d');
    let fontStyle = ' Arial, sans-serif';
    
    anim(0);
    // the animation loop
    function anim(time) {
      // call the drawing methods
      draw(Math.round(time/1e2));
      // lwoer the flags
      dirtySize = false;
      // do it again next frame
      requestAnimationFrame(anim);
    }
    
    function draw(txt) {
      // clear
      ctx.clearRect(0,0,canvas.width, canvas.height);
      // only if needed
      if(dirtySize) {
        // get the cpmputed style from our DOM element
        const fontSize = getComputedStyle(canvas).fontSize;
        // or could be 
        // const fontSize = (innerWidth / (100 / 20)) + 'px';
    
        ctx.font = fontSize + fontStyle;
      }
      // draw everytime
      ctx.fillText(txt, 0, 100);
    }
    // on window's resize event
    window.addEventListener('resize',
      evt => dirtySize = true, // raise our flag
      { passive: true }
    );
    #canvas {
      font-size: 20vw;
    }
    <canvas id="canvas"></canvas>

    【讨论】:

    • font 属性始终设置在绘图循环内,然后在画布上绘制文本。仅此一项并不能更新实际大小。可以在上面的三行代码中查看。
    • @DiegoS。哦,我现在明白了,对不起,我误读了您的问题并回答了一般情况。现在我看到它实际上是一个 webkit 错误(在 Chrome 和 Safari 中),因为我在 FF 上所以我没有注意到它......将编辑。
    猜你喜欢
    • 1970-01-01
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多