为什么我只得到一个矩形?

Why I'm getting only one rectangle?

let canvas, ctx, W, H;
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext('2d');
let objArr = [];

const init = () => {
  canvas.width = W = innerWidth;
  canvas.height = H = innerHeight;
  canvas.style.background = '#dedfda';

  for (let i = 0; i <= 5; i++) {
    let r = (i + 1) * 20;
    objArr.push(new Rectangle(W / 2, H / 2, 10, 10, "red", innerWidth / 2, innerHeight / 2, r));
    objArr[0].draw();

  }

  animate();
}

const random = (min = 0, max = 1) => Math.random() * (max - min) + min;

class Rectangle {
  constructor(posX, posY, w, h, color, cx, cy, r) {
    this.posX = posX;
    this.posY = posY;
    this.w = w;
    this.h = h;
    this.color = color;
    this.cx = cx;
    this.cy = cy;
    this.r = r;
    this.angle = 0;
  }
  draw() {
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    ctx.fillStyle = this.color;
    ctx.fillRect(this.posX, this.posY, this.w, this.h);
  }
  update() {
    this.angle += 0.1;
    this.posX = this.cx + this.r * Math.cos(this.angle);
    this.posY = this.cy + this.r * Math.sin(this.angle);
    this.draw();
  }
}



const animate = () => {
  objArr.forEach(e => {
    e.update();
  })
  requestAnimationFrame(animate);
}

window.onload = init;

在此代码中,我期望输出有 5 个矩形围绕 window 的中心点旋转,半径不同,就像太阳系中的行星围绕太阳旋转一样。

但我只得到一个矩形,而且它甚至没有旋转。

卡住了,不明白为什么它不起作用。

您只画了一个矩形。关注

objArr[0].draw()

应该是

objArr[i].draw()

此外,我认为每次 Rectange 对象的 draw 方法被调用时,整个 canvas 都会在这一行被清除

ctx.clearRect(0, 0, innerWidth, innerHeight);

因此,始终只出现一个矩形。

一个解决方案是将对 clearRectupdate 的调用从 Rectangle 移动到 animate 函数。这样更符合程序逻辑。作为对象的 Rectangle 应该只知道如何绘制自身而不清除 canvas 并更新其在 canvas.

上的位置

下面是我的解决方案。

let canvas, ctx, W, H;
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext('2d');
let objArr = [];

const init = () => {
  canvas.width = W = innerWidth;
  canvas.height = H = innerHeight;
  canvas.style.background = '#dedfda';

  for (let i = 0; i <= 5; i++) {
    let r = (i + 1) * 20;
    objArr.push(new Rectangle(W / 2, H / 2, 10, 10, "red", innerWidth / 2, innerHeight / 2, r));
    objArr[i].draw();

  }

  animate();
}

const random = (min = 0, max = 1) => Math.random() * (max - min) + min;

class Rectangle {
  constructor(posX, posY, w, h, color, cx, cy, r) {
    this.posX = posX;
    this.posY = posY;
    this.w = w;
    this.h = h;
    this.color = color;
    this.cx = cx;
    this.cy = cy;
    this.r = r;
    this.angle = 0;
  }
  draw() {
    ctx.fillStyle = this.color;
    ctx.fillRect(this.posX, this.posY, this.w, this.h);
  }

  // Should be moved outside of this class.
  update() {
    this.angle += 0.1;
    this.posX = this.cx + this.r * Math.cos(this.angle);
    this.posY = this.cy + this.r * Math.sin(this.angle);
    ctx.fillRect(this.posX, this.posY, this.w, this.h)
  }
}

const animate = () => {
  ctx.clearRect(0, 0, innerWidth, innerHeight);
  objArr.forEach(e => {
    e.update();
  })
  requestAnimationFrame(animate);
}

window.onload = init;

您的 draw 函数每次都在清除,您只引用数组的第一个元素。两者的调整显示 6 个物体在旋转。您的循环从 0 运行到 5。如果您想要 5 个对象,则需要将上限设置为 4。

let canvas, ctx, W, H;
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext('2d');
let objArr = [];

const init = () => {
  canvas.width = W = innerWidth;
  canvas.height = H = innerHeight;
  canvas.style.background = '#dedfda';

  // adjusted range
  for (let i = 0; i <= 4; i++) {
    let r = (i + 1) * 20;
    objArr.push(new Rectangle(W / 2, H / 2, 10, 10, "red", innerWidth / 2, innerHeight / 2, r));
    objArr[i].draw();
  }

  animate();
}

const random = (min = 0, max = 1) => Math.random() * (max - min) + min;

class Rectangle {
  constructor(posX, posY, w, h, color, cx, cy, r) {
    this.posX = posX;
    this.posY = posY;
    this.w = w;
    this.h = h;
    this.color = color;
    this.cx = cx;
    this.cy = cy;
    this.r = r;
    this.angle = 0;
  }
  draw() {
    ctx.fillStyle = this.color;
    ctx.fillRect(this.posX, this.posY, this.w, this.h);
  }
  update() {
    this.angle += 0.1;
    this.posX = this.cx + this.r * Math.cos(this.angle);
    this.posY = this.cy + this.r * Math.sin(this.angle);
    this.draw();
  }
}

const animate = () => {
  // moved clear here to happen just once on each animate
  ctx.clearRect(0, 0, innerWidth, innerHeight);
  objArr.forEach(e => {
    e.update();
  })
  requestAnimationFrame(animate);
}

window.onload = init;