Keeeeeeegs
Keeeeeeegs

Reputation: 11

HTML Canvas Separating Strokes

I made a simple canvas program that draws a spiral starting from the canvas's center, using a line that constantly has new points drawn. It works until another shape or line is added, and I can't think of any way to fix it. Is there any way to separate these two strokes without using a beginPath() before the lineTo()?

const canvas = document.querySelector("canvas");
canvas.width = innerWidth;
canvas.height = innerHeight;
const c = canvas.getContext("2d");

let x, y;
let i = 0;
const animate = function() {
    requestAnimationFrame(animate);
    c.clearRect(0, 0, canvas.width, canvas.height);

    c.lineTo(x, y);
    c.stroke();

    // c.beginPath();
    // c.beginPath();
    // c.arc(canvas.width / 2, canvas.height / 2, 20, 0, Math.PI * 2, false);
    // c.strokeStyle = "red";
    // c.stroke();
    // c.closePath();

    x = canvas.width / 2 + Math.cos(i * Math.PI / 180) * i;
    y = canvas.height / 2 + Math.sin(i * Math.PI / 180) * i;
    i += 5;
}

animate();

Upvotes: 0

Views: 46

Answers (1)

obscure
obscure

Reputation: 12891

The drawing of your spiral is possible because the lineTo() method draws a straight line from the current path's last position to the position given as a parameter. As you realized, this breaks as soon as you add a new path somewhere in-between.

One possible solution is keeping track of the positions that make up the spiral instead of trying to draw it right away. To do this we can fill a simply array with object's holding the x and y values for the spiral's segments.

For example:

const canvas = document.querySelector("canvas");
canvas.width = innerWidth;
canvas.height = innerHeight;
const c = canvas.getContext("2d");

let x, y;
let i = 0;
let points = [];
const animate = function() {
  requestAnimationFrame(animate);
  c.clearRect(0, 0, canvas.width, canvas.height);


  c.beginPath();
  c.arc(canvas.width / 2, canvas.height / 2, 20, 0, Math.PI * 2, false);
  c.strokeStyle = "red";
  c.stroke();
  c.closePath();

  points.push({
    x: canvas.width / 2 + Math.cos(i * Math.PI / 180) * i,
    y: canvas.height / 2 + Math.sin(i * Math.PI / 180) * i
  });
  c.beginPath();
  c.strokeStyle = "black";
  c.moveTo(points[0].x, points[0].y);
  if (points.length > 1) {
    for (let a = 0; a < points.length; a++) {
      c.lineTo(points[a].x, points[a].y);
    }
  }
  c.stroke();
  c.closePath();
  i += 5;
}

animate();
<canvas></canvas>

Upvotes: 1

Related Questions