CanvasRenderingContext2d.arc() is a method used to create a circle, or a curved segment of a circle.
Let's grab a reference to our 300x300 canvas:
<canvas id="canvas" height="300" width="300"></canvas>
const ctx = document.getElementById('canvas').getContext('2d');
In order to create an arc, you need the x,y coordinate of the arc's center, the radius, the starting angle, the ending angle, and the optional anticlockwise boolean value (default false).
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
This seems simple enough. To create a full circle, your start angle would be 0 and your end angle would be 2*Math.PI, or if you prefer degrees to radians, 360*(Math.PI/180). You can omit a value for anticlockwise since it's a full circle and it doesn't matter whether it's true or false.
This creates a grey circle with a 3px black border in the center of the canvas. I created grid lines so it's easier to see what's going on.
const radius = 40; ctx.lineWidth = 3; ctx.strokeStyle = 'black'; ctx.fillStyle = 'grey'; ctx.beginPath(); ctx.arc(canvas.width/2, canvas.height/2, radius, 0, 2*Math.PI) ctx.fill(); ctx.stroke();
I found creating arcs a little confusing at first and I'll explain why. Take 90° for example:
ctx.arc(50, 90, 40, 0, 90*(Math.PI/180))
I expected the arc to match up with the 90° on the unit circle in the positive y direction but instead it arcs down into the negative y direction. I know the direction it's moving is clockwise and 0 is the starting point, but I still thought it would move clockwise along an invisible circle from 0 to 90°, and fill in the arc between 90° and 0. I'm thinking it creates the arc opposite to what I expect because with HTML Canvas the top of the grid is the negative y direction and the bottom is the positive y direction. If you have a better understanding, please leave a comment.
Here are some more examples so you can see different degrees clockwise and counterclockwise. Pretend each arc is created separately, using
ctx.stroke() for each one as shown in the first example. For the image, I also created a point (which is just a mini filled-in arc) in the center x,y of each arc and changed the
strokeStyle (color) of each one so it's easier to visualize.
// clockwise no need for anticlockwise value since false is default ctx.arc(50, 90, 40, 0, 90*(Math.PI/180)); ctx.arc(150, 90, 40, 0, 180*(Math.PI/180)); ctx.arc(250, 90, 40, 0, 270*(Math.PI/180)); ctx.arc(50, 90, 210, 0, 360*(Math.PI/180)); // counterclockwise - same as above except anticlockwise is true ctx.arc(50, 90, 40, 0, 90*(Math.PI/180), true); ctx.arc(150, 90, 40, 0, 180*(Math.PI/180), true); ctx.arc(250, 90, 40, 0, 270*(Math.PI/180), true); ctx.arc(50, 90, 210, 0, 360*(Math.PI/180), true);
You can also use
closePath() to connect the endpoints:
// 90deg example ctx.beginPath(); ctx.arc(50, 90, 40, 0, 90*(Math.PI/180)); ctx.closePath(); ctx.stroke();
You can fill in the arcs:
// 90deg example ctx.beginPath(); ctx.arc(50, 90, 40, 0, 90*(Math.PI/180)); ctx.closePath(); ctx.fill(); ctx.stroke();
Hopefully this is helpful to someone else who may not have understood why they weren't getting the results they might have expected.