JSFiddle - React, Tailwind, and code Playground
by Vladimir
HTML
<div class="wrapper">
<div class="block1"></div>
<div class="block2"></div>
<div class="key"></div>
</div>
CSS
.wrapper {
width: 960px;
height: 720px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
background-image: url(http://beerhold.it/960/722);
background-repeat: no-repeat;
backgorund-position: center center;
position: relative;
}
.key {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 10em;
height: 10em;
border: 2em solid rgba(255, 255, 255, .3);
border-radius: 10em;
}
.block1,
.block2 {
position: absolute;
top: 0;
width: 100%;
height: 720px;
}
.block1 {
left: 0;
background-color: rgba(255, 0, 0, .2);
}
.block2 {
right: 0;
background: rgba(0, 0, 0, 0.7);
}
JavaScript
var r = 16; // радиус круга в %
var steps = 36; // количество точек полигона, чем больше - тем точнее окружность
var rezArray = [];
var startY = 50 - r;
var pathY = 2*r;
var stepY = pathY/steps;
for(var i = 0; i < steps; i++) {
var dotY = startY + stepY*i;
var dotX = i==0? 0: Math.pow((r*r - (r-stepY*i)*(r-stepY*i)), 0.5);
dotX = dotX * 720/960; // коэф. соотношения сторон (т.к. полигон задается в процентах, а картинка не квадратная)
dotX = 50 - dotX;
rezArray.push(dotX + "% " + dotY +"%");
}
rezArray.push("50% " + (startY+pathY) +"%");
var clipPath = "polygon(100% 0%, 50% 0%, " + rezArray.join(", ") + ", 50% 100%, 100% 100%)";
console.log(clipPath);
$(".block2").css("clip-path", clipPath);
var clipPath2 = "polygon(0% 0%, 50% 0%, " + rezArray.join(", ") + ", 50% 100%, 0% 100%)";
console.log(clipPath2);
$(".block1").css("clip-path", clipPath2);