Обрезка по фигуру
Описание
Есть такая конструкция:
body {
background-color: lightgrey;
}
div {
display: flex;
box-sizing: border-box;
margin: 0;
background-color: white;
border: 2px solid grey;
}
<div style="position: relative; width: 100px; height: 100px; align-items: center;">
<div style="width: 75px; height: 75px; position: absolute; right: -37.5px; padding: 8px; border-radius: 50%; background-color: orange;">
<div style="width: 100%; height: 100%; border-radius: inherit;"></div>
</div>
</div>
Вопрос
Каким способом можно вырезать оранжевую часть так, чтобы остались только белые части?
Примерно вот так:
Дополнение
Попробовал с background-clip, clip-path. Оранжевая часть вырезается, но белый квадрат сзади остается. Получается вот так:
И ещё одно уточнение
Сверху — упрощенный пример этого сайта. Пример может не включать себе некоторые детали, которые рассмотрены в сайте, ведь это минимальный запускаемый пример. Просьба, предложить такие решения которые можно реализовать в сайте.
Ответы (2 шт):
Ну я так смог только решить эту проблему
В --bs-color я вписал цвет заднего фона и вывожу потом задний фон и outer-round через переменную
--bs-color: white;
body {
background-color: lightgrey;
}
div {
display: flex;
box-sizing: border-box;
margin: 0;
background-color: white;
border: 2px solid grey;
}
.outer-round {
width: 75px;
height: 75px;
position: absolute;
right: -37.5px;
padding: 10px;
border-radius: 50%;
background-color: --bs-color;
border-bottom: 2px solid grey;
border-right: 2px solid transparent;
border-left: 2px solid grey;
border-top: 2px solid transparent;
transform:rotate(45deg);
}
<div style="position: relative; width: 100px; height: 100px; align-items: center;">
<div class="outer-round">
<div class="inner-round" style="width: 100%; height: 100%; border-radius: inherit;"></div>
</div>
</div>
// for demo
[...document.querySelectorAll('#control input')].map(el => {
['change', 'mousemove'].map(event_name => {
el.addEventListener(event_name, ({target}) => {
document.querySelector('.block').style.setProperty('--'+target.id, target.value+'%');
document.querySelector(`label[for="${target.id}"]`).dataset.val = target.value;
});
});
});
/* for demo */
#control {color: #fff; font-family: monospace; position: fixed; left: 0; top: 0; z-index: 1;}
label {display: flex; align-items: center;}
label:not(:last-child) {margin-bottom: 20px;}
label::after {content: attr(data-val)'%'; display: inline;}
input {width: 100px; margin: 0 5px;}
body {display: flex; justify-content: center; align-items: center; min-height: 100vh; background: url(https://i.imgur.com/HYAdZOO.png) no-repeat center center / cover; margin: 0; overflow: hidden;}
/* /for demo */
.block {
--x: 0;
--y: 0;
--stroke: 10px;
--size: 60px;
display: block;
width: 200px;
height: 200px;
position: relative;
}
.block .mask {
display: block;
width: 100%;
height: 100%;
-webkit-border-radius: 10px;
border-radius: 10px;
background-color: #fff;
-webkit-mask-image:
-webkit-radial-gradient(var(--x) var(--y),
circle,
transparent -webkit-calc(var(--size) / 2 + var(--stroke)),
white -webkit-calc(var(--size) / 2 + var(--stroke) + 1px)
);
mask-image:
radial-gradient(circle at var(--x) var(--y),
transparent -moz-calc(var(--size) / 2 + var(--stroke)),
white -moz-calc(var(--size) / 2 + var(--stroke) + 1px)
);
mask-image:
radial-gradient(circle at var(--x) var(--y),
transparent calc(var(--size) / 2 + var(--stroke)),
white calc(var(--size) / 2 + var(--stroke) + 1px)
);
position: absolute;
left: 0;
top: 0;
}
.block .image {
display: block;
width: var(--size);
height: var(--size);
-webkit-border-radius: 50%;
border-radius: 50%;
background-color: red;
padding: 5px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
left: var(--x);
top: var(--y);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
<!-- for demo -->
<div id="control">
<label for="x" data-val="0">X <input id="x" type="range" min="0" max="100%" value="0"></label>
<label for="y" data-val="0">Y <input id="y" type="range" min="0" max="100%" value="0"></label>
</div>
<!-- /for demo -->
<div class="block">
<div class="mask"></div>
<div class="image">
<img src="https://i.imgur.com/LjYw4LU.gif" width="50">
</div>
</div>
Использую mask'у, фигуру задаю такую же, как .image, в нашем случае это круг - для этого использую radial-gradient, размер этого круга такой же как размер .image + область "под вырез" (переменная --stroke).
Позиционирую как mask'у, так и .image относительно .block (переменные --x и --y), так же .image смещён через transform.
.mask и .image лежат на одном уровне, т.к. если вложить .image в .mask, то .image будет обрезаться mask'ой.

