JSFiddle - React, Tailwind, and code Playground
by Case Mate
HTML
<canvas id="canvas" width="300" height="250" style="background-color: #f1f1f1;"></canvas>
JavaScript
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var redRect = {
x: 33,
y: 33,
width: 200,
height: 60,
color: '#af0000'
};
var blackRect = {
x: 77,
y: 66,
width: 120,
height: 60,
color: '#000'
};
var blackRectHole = {
x: 110,
y: 80,
width: 20,
height: 20
};
var cvRect = {
x: 0,
y: 0,
width: canvas.width,
height: canvas.height
};
function drawRect(rect) {
ctx.beginPath();
ctx.fillStyle = rect.color;
ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
ctx.closePath();
}
function drawRectClipped(rect, clipRect) {
ctx.save();
clipOut(clipRect);
drawRect(rect);
ctx.restore();
}
function clipOut(clipRect) {
ctx.beginPath();
rectPath(cvRect);
ctx.lineTo(clipRect.x, clipRect.y);
rectPath_ccw(clipRect);
ctx.clip();
}
function rectPath(rect) {
ctx.moveTo(rect.x, rect.y);
ctx.lineTo(rect.x + rect.width, rect.y);
ctx.lineTo(rect.x + rect.width, rect.y + rect.height);
ctx.lineTo(rect.x, rect.y + rect.height);
ctx.lineTo(rect.x, rect.y);
}
function rectPath_ccw(rect) {
ctx.moveTo(rect.x, rect.y);
ctx.lineTo(rect.x, rect.y + rect.height);
ctx.lineTo(rect.x + rect.width, rect.y + rect.height);
ctx.lineTo(rect.x + rect.width, rect.y);
ctx.lineTo(rect.x, rect.y);
}
drawRect(redRect);
drawRectClipped(blackRect, blackRectHole);