繁体   English   中英

如何使用 HTML Canvas 保存先前动画帧的值?

[英]How to save values from previous Animation Frames using HTML Canvas?

我正在尝试使用 HTML 画布为一组圆圈设置动画。 我还尝试保存圆的先前信息,以便能够确定速度向量供以后使用。 但是我似乎无法将以前的圆圈保存在全局变量中。 即使圆的位置发生变化,注销圆数组和前一个数组也会返回相同的值。

 class Vector { constructor(x, y) { this.x = x; this.y = y; } static subst(vector1, vector2){ return new Vector(vector1.x - vector2.x, vector1.y - vector2.y) } static divd(vector, scalar){ return new Vector(vector.x/scalar,vector.y/scalar) } } class Circle { constructor(x,y, radius,color,isGrabbed) { this.pos = new Vector(x,y) this.radius = radius; this.color = color; this.velocity = new Vector(0,0); this.isGrabbed = isGrabbed; } draw(ctx){ ctx.beginPath(); ctx.arc(this.pos.x, this.pos.y, this.radius, 0, Math.PI*2) ctx.fillStyle = this.color; ctx.fill() } update(prevPos){ this.velocity = Vector.subst(this.pos, prevPos) console.log(this.velocity) } } let circles = [] circles.push(new Circle(300, 400, 70, "red", false)) circles.push(new Circle(500, 300, 70, "green", false)) circles.push(new Circle(800, 600, 70, "yellow", false)) let previous = [] // variable for the previous circle array function update(){ ctx.clearRect(0,0, canvas.width, canvas.height) // iterating through the array of circles and drawing them onto the canvas for(let i = 0; i< circles.length; i++){ circles[i].pos.x +=10; // changes the circle's x-position on every animation frame if(previous.length>0){ circles[i].update(previous[i].pos) console.log(previous[i].pos.x,circles[i].pos.x) // both values are the same } } // saving the previous array of circles for(let i = 0; i< circles.length; i++){ previous[i] = circles[i] } requestAnimationFrame(update) }

我没有完全理解代码,但是您对circle array and the previous array gives back the same values提出疑问circle array and the previous array gives back the same values有一个答案。

这一行previous[i] = circles[i]有错误。 它不复制 Circle,它使用旧的(链接到对象的引用),因此如果您更改新值,旧的也将更改。

您可以尝试真正复制圆圈。 这是一个例子

// saving the previous array of circles
for (let i = 0; i< circles.length; i++) {
    let clone = Object.assign( Object.create( Object.getPrototypeOf(circles[i])), circles[i]);
    previous[i] = clone;
}

但是,如果我正在执行此代码,我会将“速度”或“前一个”保留在对象本身中。

所以这将受到限制: circles[i].pos.x +=10; . 相反,我们将使用 setter:

class Circle {
  ...
  setPos(newPos) {
    this.velocity = Vector.subst(newPos, this.pos);
    this.pos.x = newPos.x;
    this.pos.y = newPos.y;
  },
  // this is not needed anymore:
  //update(prevPos){
  //   this.velocity = Vector.subst(this.pos, prevPos)
  //   console.log(this.velocity)
  //}
}

...
// So this line: circles[i].pos.x +=10; will be converted to:
circles[i].setPos(new Vector(circles[i].x + 10, circles[i].y));

PS setPos(newPos)可以更改为setPos(x,y) ,因此它会稍微简化代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM