All circles being drawn in the same colour

Viewed 47

Shortly summarized the problem is this. I want to draw two circles on the canvas with different colors. For some reason, they are drawn in the same color, even though the console log I have placed in is switching between "green" and "blue". Sorry that some of the variable names are in my native language if that poses a problem just ask and I'll translate it.

var bodyEl = document.querySelector("body");
var canvasEl = document.createElement("canvas");
var height = window.innerHeight;
var width = window.innerWidth;
canvasEl.height = height;
canvasEl.width = width;
bodyEl.appendChild(canvasEl);
var ctx = canvasEl.getContext("2d");
var obj = [];

class ball {
  constructor(radius, farge, xPosisjon, yPosisjon) {
    this.x = xPosisjon;
    this.y = yPosisjon;
    this.rad = radius;
    this.farge = farge;
  }
  get areal() {
    let areal = "areal: " + (Math.PI * this.rad * this.rad + "px");
    return (areal);
  }
  tegn() {
    //console.log(this.farge);
    ctx.fillStyle = this.farge;
    ctx.arc(this.x, this.y, this.rad, 0, 2 * Math.PI);
    ctx.fill();
  }
}

obj.push(new ball(20, "green", 100, 100));
obj.push(new ball(30, "blue", 500, 300));

setInterval(() => {
  obj.forEach(x => {
    x.tegn();
  });
}, 30);

3 Answers

You need to add a ctx.beginPath().

The reason you are seeing the same color is related to the same problem found in this question: Drawing lines with canvas by using for loop. If you don't use beginPath(), you keep pushing draw commands to the same (root) path and then drawing the ever increasingly complex path.

You have to use beginPath to start a sub-path. ctx.fill() will close the sub-path. The closePath is optional.

The third, and an optional step, is to call closePath(). This method tries to close the shape by drawing a straight line from the current point to the start. If the shape has already been closed or there's only one point in the list, this function does nothing.

var bodyEl = document.querySelector("body");
var canvasEl = document.createElement("canvas");
var height = window.innerHeight;
var width = window.innerWidth;
canvasEl.height = height;
canvasEl.width = width;
bodyEl.appendChild(canvasEl);
var ctx = canvasEl.getContext("2d");
var obj = [];

class ball {
  constructor(radius, farge, xPosisjon, yPosisjon) {
    this.x = xPosisjon;
    this.y = yPosisjon;
    this.rad = radius;
    this.farge = farge;
  }
  get areal() {
    let areal = "areal: " + (Math.PI * this.rad * this.rad + "px");
    return (areal);
  }
  tegn() {
    //console.log(this.farge);
    ctx.beginPath();
    ctx.fillStyle = this.farge;
    ctx.arc(this.x, this.y, this.rad, 0, 2 * Math.PI);
    ctx.fill();
  }
}

obj.push(new ball(20, "green", 100, 100));
obj.push(new ball(30, "blue", 500, 300));

setInterval(() => {
  ctx.clearRect(0,0,500,500);
  obj.forEach(x => {
    x.tegn();
  });
}, 1000);

your paths are being drawn in the correct colors, but your second (blue) arc is drawing on top of your first (green) one. at the top of your tegn method, add a call to ctx.beginPath() to let your canvas know that your paths should be independent.

You missed beginPath.

var bodyEl = document.querySelector("body");
var canvasEl = document.createElement("canvas");
var height = window.innerHeight;
var width = window.innerWidth;
canvasEl.height = height;
canvasEl.width = width;
bodyEl.appendChild(canvasEl);
var ctx = canvasEl.getContext("2d");
var obj = [];

class ball {
  constructor(radius, farge, xPosisjon, yPosisjon) {
    this.x = xPosisjon;
    this.y = yPosisjon;
    this.rad = radius;
    this.farge = farge;
  }
  get areal() {
    let areal = "areal: " + (Math.PI * this.rad * this.rad + "px");
    return (areal);
  }
  tegn() {
    //console.log(this.farge);
    ctx.beginPath();
    ctx.fillStyle = this.farge;
    ctx.arc(this.x, this.y, this.rad, 0, 2 * Math.PI);
    ctx.fill();
  }
}

obj.push(new ball(20, "green", 100, 100));
obj.push(new ball(30, "blue", 500, 300));

setInterval(() => {
  obj.forEach(x => {
    x.tegn();
  });
}, 30);

Related