简体   繁体   中英

Change canvas fillStyle in loop

I want to assign each circle created in this loop to it's respective color. Now they are all being set to the same color although each $circle object has a different color. I read that i need to close the path or fill before the next loop which im pretty sure i did but it still didn't work. My code is below:

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();
            }

You have to start new path for each fillStyle or strokeStyle operation as they are tied to the current path, so simply move those methods inside the loop so a new path is created for each circle and fill operation.

What happens now is that the path is cleared once, then per iteration a new arc is added. The canvas is cleared but not the path, and it has a new fill style so all arcs on the path are redrawn using the last fill style.

You are also clearing the canvas for each iteration which is not needed here (it's not so obvious since the path is not cleared so all circles are redrawn as stated above) - it could be called before anything is drawn though if animation is the goal.

And moveTo() should be called before arc() , or it would be pointless; since a new path is created it's not really needed but I left it in there.

// 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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