Canvas修改宽高致浏览器/VS实时预览崩溃问题求助
问题原因
- 死循环导致页面卡死:
drawPixels函数的循环终止条件依赖起点、终点坐标是pixelSize的整数倍,当Canvas宽高设为300×300时,sq = 300,计算出的x2 = 150,而pixelSize=20,150不是20的整数倍。循环中x每次步进20,永远无法等于150,y也无法精准到达终点0,导致while(true)无限执行,CPU被占满,表现为浏览器/实时预览崩溃。 - 400×400时
x2=200是20的整数倍,循环能正常终止,因此无异常。 - 偶尔刷新恢复是预览环境临时状态波动,并非根本解决方法。
解决办法
方案1:确保坐标为pixelSize的整数倍
调整坐标计算逻辑,让所有绘制的起点、终点坐标都是pixelSize的整数倍,避免循环无法终止:
var sq = Math.min(rectHeight, rectWidth); var pixelSize = 20; // 将x2修正为pixelSize的整数倍 var x2 = Math.round(sq / 2 / pixelSize) * pixelSize; var y2 = 0; var x1 = 0; var y1 = sq; var x3 = sq; var y3 = sq;
方案2:修改循环终止条件
放弃坐标完全相等的判断,改为判断当前坐标是否已越过终点,适配所有坐标情况:
function drawPixels(ctx, x1, y1, x2, y2, pixelSize, color) { const dx = Math.abs(x2 - x1); const dy = Math.abs(y2 - y1); const sx = x1 < x2 ? 1 : -1; const sy = y1 < y2 ? 1 : -1; let err = dx - dy; let x = x1; let y = y1; while (true) { ctx.fillStyle = color; ctx.fillRect(x, y, pixelSize, pixelSize); // 判断坐标是否已到达或越过终点,终止循环 if ((sx > 0 ? x >= x2 : x <= x2) && (sy > 0 ? y >= y2 : y <= y2)) break; const err2 = 2 * err; if (err2 > -dy) { err -= dy; x += sx * pixelSize; } if (err2 < dx) { err += dx; y += sy * pixelSize; } } }
额外优化
代码中先获取绘图上下文再修改Canvas高度的操作存在隐患:修改Canvas宽/高会重置上下文状态,建议调整顺序:
var canvas = document.getElementById("myCanvas"); var pixelSize = 20; // 先修改Canvas尺寸 canvas.height += pixelSize; // 再获取绘图上下文 var ctx = canvas.getContext("2d"); var rectWidth = canvas.width; var rectHeight = canvas.height;
内容的提问来源于stack exchange,提问作者duxa
相关产品推荐
相关产品推荐

