https://jsfiddle.net/diegojsrw/od12s9b4/14/
c.font = "100vh sans-serif";
c.fillStyle = "white";
c.fillText(fps.toFixed(0), w/2, 0);
最初,文本的高度看起来不错。
但是,当我调整窗口大小时,文本不会一起调整大小。文本不断地在画布上绘制(使用requestAnimationFrame
)。
仅当我切换到另一个标签然后再切换回该标签时,才重新调整文本大小。
有任何线索吗?
答案 0 :(得分:1)
在Canvas2D API中,应该在设置时计算相对单位/值,并且此计算值将被保存和使用。
这意味着您的相对100vw
值将以绝对的px
单位计算为其对应的值。
这是建议始终使用canvas API中的绝对单位的原因之一(尤其是舍入调整等)。
但是,如果您确实要使用此单元,则每次更改它时都必须对其进行设置,因此您可以盲目地进入循环,只需在调用ctx.font
之前再次设置fillText()
,但是为了提高性能,我建议您使用脏标志,该标志会在窗口的resize
事件中引发,并且仅在引发该标志时更新ctx.font
属性。 / p>
我不确定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>