I'm try to create a compound clip path in canvas to create a donut-like clip path.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw() {
ctx.save();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.arc(200, 200, 30, 0, Math.PI * 2, true);
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);
ctx.clip();
ctx.fillRect(0,0,500,400);
}
draw();
As you can see in my jsfiddle, this is not working: https://jsfiddle.net/nahman/05jcjkvn/
What I've found is if I change it to use two different shape types -- arc and rect, arc and path -- it works, but I need to be able to use two of the same: https://jsfiddle.net/nahman/9wmvLea7/
My questions are:
Why does it not work with two of the same object types but does with different ones? Are there any good resources explaining this? My google searches have turned up sadly empty...
How can I fix this? :)
I should note that I have currently forced the behavior I want by drawing the smaller clip after my drawing and then applying a clearRect, (https://jsfiddle.net/nahman/pg6ya2ob/) but for a variety of reasons would prefer to understand what is going on and do it more properly if possible.
Have a look at Clip and fill rules article
You need to specify correct filling rule, "evenodd" for your case.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw() {
ctx.save();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);
ctx.arc(200, 200, 30, 0, Math.PI * 2, true);
ctx.clip("evenodd");
ctx.fillRect(0,0,500,400);
}
draw();
<canvas id="canvas" width=500 height=400></canvas>