【问题标题】:Change canvas fillStyle in loop在循环中更改画布填充样式
【发布时间】:2017-09-09 05:28:38
【问题描述】:

我想将在此循环中创建的每个圆圈分配给它各自的颜色。现在它们都被设置为相同的颜色,尽管每个 $circle 对象都有不同的颜色。我读到我需要在下一个循环之前关闭路径或填充,我很确定我这样做了,但它仍然不起作用。我的代码如下:

drawCircles: function () {
                this.ctx.beginPath();
                for(var i = 0; i < this.circles.length; i++){
                    var $circle = this.circles[i];
                    this.ctx.fillStyle = $circle.color; //blue

                    var tx = $circle.destX - $circle.x,
                        ty = $circle.destY - $circle.y,
                        dist = Math.sqrt(tx*tx+ty*ty);

                    if(tx > 0){
                        $circle.x += (tx/dist) * ($circle.speed > 0 ? $circle.speed -= 0.005 : $circle.speed += .2);
                        $circle.y += (ty/dist) * ($circle.speed > 0 ? $circle.speed -= 0.005 : $circle.speed += .2);
                    }

                    this.ctx.arc($circle.x,$circle.y,$circle.size,0,Math.PI*2);


                    this.ctx.clearRect(0,0,this.ctx.canvas.width, this.ctx.canvas.height);
                    this.ctx.moveTo($circle.x + $circle.size, $circle.y); // so simply add 'rad' to the centerX
                }
                this.ctx.closePath();
                this.ctx.fill();
            }

【问题讨论】:

  • 你不需要 closePath,。但你需要在每条不同颜色的弧线之前有一个 beginPath。

标签: javascript canvas


【解决方案1】:

您必须为每个 fillStylestrokeStyle 操作启动新路径,因为它们与当前路径相关联,因此只需将这些方法移动到循环内,以便为每个圆圈和填充操作创建一个新路径。

现在发生的情况是路径被清除一次,然后每次迭代都会添加一条新弧。画布被清除,但路径没有被清除,并且它具有新的填充样式,因此路径上的所有弧都使用最后的填充样式重绘。

您还清除了这里不需要的每次迭代的画布(它不是很明显,因为路径没有被清除,所以所有的圆圈都如上所述重绘) - 尽管如果动画是,它可以在绘制任何东西之前被调用目标。

并且moveTo()应该在arc()之前调用,否则没有意义;由于创建了一条新路径,因此并不需要它,但我把它留在了那里。

// clearRect moved out of loop:
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);

//this.ctx.beginPath();  // move inside loop
for (var i = 0; i < this.circles.length; i++) {
  this.ctx.beginPath();  // here

  var $circle = this.circles[i];
  this.ctx.fillStyle = $circle.color; //blue

  var tx = $circle.destX - $circle.x,
      ty = $circle.destY - $circle.y,
      dist = Math.sqrt(tx * tx + ty * ty);

  if (tx > 0) {
    $circle.x += (tx/dist)*($circle.speed>0 ? $circle.speed-=0.005 : $circle.speed += .2);
    $circle.y += (ty/dist)*($circle.speed>0 ? $circle.speed-=0.005 : $circle.speed += .2);
  }

  // use moveTo OP before adding the arc()
  this.ctx.moveTo($circle.x + $circle.size, $circle.y);
  this.ctx.arc($circle.x, $circle.y, $circle.size, 0, Math.PI * 2);

  this.ctx.fill();       // here
}
//this.ctx.closePath();  // not needed for fill
//this.ctx.fill();       // move inside loop

【讨论】:

    猜你喜欢
    • 2013-09-07
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多