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

Canvas创建对象异常:最后一个对象颜色覆盖全部问题求助

问题:Canvas创建多色正方形时全部显示为最后一个颜色

问题描述

使用Canvas和自定义GameObject类创建三个不同颜色的正方形,实际渲染后所有正方形都变成最后创建的绿色,预期是蓝、红、绿三个不同颜色的正方形。

现象截图:
三个绿色正方形的Canvas渲染结果

原代码:

<canvas id="myCanvas" width="480" height="320"></canvas>
<script>
  var canvas = document.getElementById("myCanvas");
  var ctx = canvas.getContext("2d");

  class GameObject {
    constructor(x, y, w, h, color) {
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
      this.color = color;
    }

    drawObject() {
      ctx.rect(this.x, this.y, this.w, this.h);
      ctx.fillStyle = this.color;
      ctx.fill();
    }
  }

  bluesquare = new GameObject(0, 0, 50, 50, "blue");
  bluesquare.drawObject();
  redsquare = new GameObject(50, 0, 50, 50, "red");
  redsquare.drawObject();
  greensquare = new GameObject(100, 0, 50, 50, "green");
  greensquare.drawObject();
  
</script>
<style>
  * {
    padding: 0;
    margin: 0;
  }

  canvas {
    background: rgb(167, 167, 167);
    display: block;
    margin: 0 auto;
  }
</style>

问题原因

Canvas的2D绘图上下文会累加路径:每次调用ctx.rect()时,是把当前矩形的路径添加到已有的路径集合中,而非创建新的独立路径。当最后一次调用ctx.fill()时,所有积累的路径都会被当前设置的fillStyle(最后一次的绿色)填充,导致所有正方形颜色统一为绿色。

解决方案

有两种简单的修复方式:

方式1:绘制前重置路径

在每次绘制矩形前调用ctx.beginPath(),清空当前路径集合,确保每个矩形都是独立的路径:

drawObject() {
  ctx.beginPath(); // 重置当前路径
  ctx.rect(this.x, this.y, this.w, this.h);
  ctx.fillStyle = this.color;
  ctx.fill();
}

方式2:使用fillRect直接绘制

fillRect方法会自动创建路径并完成填充,无需手动管理路径,代码更简洁:

drawObject() {
  ctx.fillStyle = this.color;
  ctx.fillRect(this.x, this.y, this.w, this.h);
}

修复后的完整代码

<canvas id="myCanvas" width="480" height="320"></canvas>
<script>
  var canvas = document.getElementById("myCanvas");
  var ctx = canvas.getContext("2d");

  class GameObject {
    constructor(x, y, w, h, color) {
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
      this.color = color;
    }

    drawObject() {
      ctx.fillStyle = this.color;
      ctx.fillRect(this.x, this.y, this.w, this.h);
    }
  }

  const bluesquare = new GameObject(0, 0, 50, 50, "blue");
  bluesquare.drawObject();
  const redsquare = new GameObject(50, 0, 50, 50, "red");
  redsquare.drawObject();
  const greensquare = new GameObject(100, 0, 50, 50, "green");
  greensquare.drawObject();
  
</script>
<style>
  * {
    padding: 0;
    margin: 0;
  }

  canvas {
    background: rgb(167, 167, 167);
    display: block;
    margin: 0 auto;
  }
</style>

内容的提问来源于stack exchange,提问作者Luigi Amari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:35:24