JSFiddle - React, Tailwind, and code Playground
HTML
<canvas id="cv" width="800" height="600"></canvas>
JavaScript
var canvasNode = document.getElementById('cv');
var ctx = canvasNode && canvasNode.getContext('2d');
var image = new Image();
image.onload = function() {
// draw the image, region has been clipped
ctx.drawImage(image, startX, startY);
// restore so that a stroke is not affected by clip
ctx.restore();
ctx.stroke();
};
image.src = "http://www.lorempixum.com/200/200/";
var startX = 200;
var startY = 0;
var rectWidth = 150;
var rectHeight = 150;
var radius = 30;
var lineWidth = rectWidth / 2 - radius;
var lineHeight = rectHeight / 2 - radius;
// typing pi is easier than Math.PI each time
var pi = Math.PI;
ctx.moveTo(startX, startY);
ctx.lineTo(startX + lineWidth, startY);
ctx.arc(startX + rectWidth / 2, startY,
radius,
pi, 0, true);
ctx.lineTo(startX + rectWidth, startY);
ctx.lineTo(startX + rectWidth, startY + lineHeight);
ctx.arc(startX + rectWidth, startY + rectHeight / 2,
radius,
-pi / 2, pi / 2, false);
ctx.lineTo(startX + rectWidth, startY + rectHeight);
ctx.lineTo(startX + rectWidth - lineWidth, startY + rectHeight);
ctx.arc(startX + rectWidth / 2, startY + rectHeight,
radius,
0, pi, false);
ctx.lineTo(startX, startY + rectHeight);
ctx.lineTo(startX, startY + rectHeight - lineHeight);
ctx.arc(startX, startY + rectHeight / 2,
radius,
pi/2, pi*3/2, true);
ctx.lineTo(startX, startY);
ctx.save(); // Save the current state without clip
ctx.clip();