Canvas宽高调整异常:JS设置后有时失效变回0×0,求解决方案
解决Canvas尺寸偶尔无法生效(变回0×0)的问题
这问题我之前调试Canvas时也踩过坑!你遇到的时好时坏的情况,核心原因几乎可以确定是代码执行时机不对——当你的initialise()函数运行时,要么DOM还没完全加载完成,要么浏览器还没计算好canvas的CSS布局尺寸,导致board.clientWidth和board.clientHeight拿到的是0,自然就把canvas设成0×0了。
下面给你几个靠谱的解决办法:
1. 确保DOM完全加载后再执行代码
把你的代码包裹在DOMContentLoaded事件监听里,保证canvas元素已经被渲染到页面上,才能正确获取它的客户端尺寸:
'use strict'; document.addEventListener('DOMContentLoaded', () => { const board = document.querySelector('.board'); const ctx = board.getContext('2d'); function initialise() { board.width = board.clientWidth; board.height = board.clientHeight; } initialise(); });
2. 监听窗口 resize 事件(必加!)
因为你给canvas设了CSS宽高100%,窗口大小变化时,canvas的显示尺寸会跟着变,但绘图缓冲区不会自动更新。所以要监听resize事件,实时同步尺寸:
'use strict'; document.addEventListener('DOMContentLoaded', () => { const board = document.querySelector('.board'); const ctx = board.getContext('2d'); function initialise() { board.width = board.clientWidth; board.height = board.clientHeight; // 如果有绘图逻辑,这里最好重新绘制内容 // drawSomething(ctx); } // 初始化尺寸 initialise(); // 窗口大小变化时重新设置 window.addEventListener('resize', initialise); });
3. 处理布局计算的异步延迟(极端情况)
有时候浏览器的布局计算会有微小延迟,即使DOM加载完成,clientWidth也可能暂时为0。这种情况可以用requestAnimationFrame延迟一帧再获取尺寸:
'use strict'; document.addEventListener('DOMContentLoaded', () => { const board = document.querySelector('.board'); const ctx = board.getContext('2d'); function initialise() { // 用requestAnimationFrame确保布局已计算 requestAnimationFrame(() => { board.width = board.clientWidth; board.height = board.clientHeight; }); } initialise(); window.addEventListener('resize', initialise); });
另外要提醒你:canvas的CSS宽高是它在页面上的显示尺寸,而JS设置的width/height是它的绘图缓冲区尺寸,两者要匹配,否则绘制的内容会拉伸变形。你的代码逻辑是对的,就是时机问题导致偶尔失效。
内容的提问来源于stack exchange,提问作者user9480234
相关产品推荐
相关产品推荐

