You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:35:54