Reputation: 11
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
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