I want to use javascript to shade in specific parts of canvas drawings on click. Here is my code below that draws a square inside a circle.
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<canvas width="300" height="300" id="myCanvas" style="border:1px solid #000000;"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.rect(centerX-25, centerY-25, 50, 50)
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
</script>
</body>
</html>
And after clicking on the area outside the square but still inside the circle, I want to just shade that part in and have something like this:
CodePudding user response:
You can simply call fill()
with the "evenodd"
filling-rule.
However, this will cover the inner-half of your current stroke, as to avoid that, you can use compositing to draw behind the current drawings:
const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.rect(centerX-25, centerY-25, 50, 50)
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
context.fillStyle = "green";
canvas.onclick = ({ clientX, clientY }) => {
const { left, top } = canvas.getBoundingClientRect();
// if we're in the circle but not the inner rect
if( context.isPointInPath( clientX - left, clientY - top, "evenodd" ) ) {
// draw behind
context.globalCompositeOperation = "destination-over";
context.fill("evenodd");
// do it only once
canvas.onclick = null;
}
};
<canvas width="300" height="300" id="myCanvas" style="border:1px solid #000000;"></canvas>