Clip path внутри круга?
Можно ли создать внутренний контур clip path круга, чтобы контур clip path эффективно прорезал отверстие через div в центре, а не только показывал центр?
Все div должны быть показаны за исключением отверстия, вырезанного в центре, чтобы создать что-то вроде этого:
хотел бы использовать clip path или что-то подобное, чтобы я мог иметь (изображения и контент) за div, и clip path будет использоваться для выявления этого. Таким образом, div (синий div из моего jsfiddle) исчезнет из центра, используя transition, чтобы показать содержимое за ним.
div {
background: blue;
width: 200px;
height: 200px;
-webkit-clip-path: circle(50px at center);
}
<div></div>
Свободный перевод вопроса Clip path inset circle? от участника @Rafty.
Ответы (5 шт):
Я не думаю, что вы можете добиться этого с помощью clip-path, но вы, безусловно, можете вырезать отверстие в div, используя фоновые изображения с радиальным градиентом. Это хорошо поддерживается браузерами.
Примечание. Этот подход (и box-shadow) будет работать только тогда, когда элемент, закрывающий содержимое ниже, имеет цветную заливку. Если вместо песочно-коричневого цвета поверх должно быть другое изображение, тогда эти подходы не будут работать, потому что они на самом деле не прорезают отверстие, а просто имитируют этот эффект.
.div-with-hole {
height: 100vh;
background: radial-gradient(circle at center, transparent 25%, sandybrown 25.5%);
background-size: 100% 100%;
background-position: 50% 50%;
transition: all 2s ease;
}
.div-with-hole:hover {
background-size: 400% 400%; /* should be 100% * (100 / transparent % of radial gradient */
}
body {
background: url(http://lorempixel.com/800/800/nature/1);
min-height: 100vh;
margin: 0;
padding: 0;
}
<div class='div-with-hole'></div>
Вы также можете сделать это с помощью box-shadow на :after псевдоэлементе
div {
position: relative;
width: 300px;
height: 200px;
overflow: hidden;
background: url('http://planetcompas.com/live/wp-content/uploads/2013/04/2015-01-Beautiful-Planet-And-Space-4-Cool-Wallpapers-HD.jpg');
background-size: cover;
background-position: center;
}
div:after {
width: 50px;
height: 50px;
content: '';
border-radius: 50%;
background: transparent;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0px 0px 0px 300px lightblue;
transition: all 0.3s linear;
}
div:hover:after {
opacity: 0;
}
<div></div>
Свободный перевод ответа от участника @Nenad Vracar.
Сделать такое в clip-path простыми фигурами (polygon, circle и т.п.) не получиться. Но, есть же ещё url() с SVG. И тут открывается возможность для реализации задуманного. Главное - творчески подойти. Вся магия в форме <path> (осторожно! "вырвиглаз"):
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
height: 100vh;
overflow: hidden;
background-image: repeating-linear-gradient(40deg, #080 10%, #fa0 12%, #c50 18%);
background-size: 100%;
animation: bg 1s infinite ease-in-out alternate;
}
.svg { position: absolute; height: 0; width: 0; }
.fon {
height: 300px; width: 400px;
clip-path: url(#my-clip-path);
animation: rot 6s infinite linear;
}
.clipped {
height: 225px; width: 300px;
background-image: url(https://source.unsplash.com/600x600?summer);
background-size: cover;
transition: 2s ease;
animation: rot 6s infinite linear reverse;
}
.clipped:hover {
height: 600px; width: 800px;
opacity: .5;
transition: 1.5s ease;
}
@keyframes rot { to { transform: rotate(360deg); } }
@keyframes bg { to { background-size: 300%; } }
<svg class="svg">
<clipPath id="my-clip-path" clipPathUnits="objectBoundingBox"><path d="M0.5,0 L0.5,0.333 A0.125,0.167,0,1,1,0.5,0.667 A0.125,0.167,0,1,1,0.5,0.333 L0.5,0 L0,0 L0,1 L1,1 L1,0"></path></clipPath>
</svg>
<div class="fon">
<div class="clipped"></div>
</div>
В виду того, что это "свободный перевод", похоже, что также "свободно" написанного вопроса, то сей ответ является тоже свободным, так как не совсем ясна суть.
Решение SVG mask
В качестве маски использована окружность, у которой анимируется радиус.
Анимация начнется посл клика
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300" viewBox="0 0 600 600" >
<defs>
<!-- Многоцветный радиальный градиент -->
<radialGradient id="grad" x1="0" y1="0" x2="100%" y2="0">
<stop offset="10%" stop-color="#48afc1" />
<stop offset="10%" stop-color="#b4c63b" />
<stop offset="20%" stop-color="#ef5b2b" />
<stop offset="20%" stop-color="#503969" />
<stop offset="30%" stop-color="#ab6294" />
<stop offset="30%" stop-color="#1cb98f" />
<stop offset="40%" stop-color="#48afc1" />
<stop offset="40%" stop-color="#b4c63b" />
<stop offset="50%" stop-color="#ef5b2b" />
<stop offset="50%" stop-color="#503969" />
<stop offset="60%" stop-color="#ab6294" />
<stop offset="60%" stop-color="#1cb98f" />
<stop offset="70%" stop-color="#48afc1" />
<stop offset="70%" stop-color="#b4c63b" />
<stop offset="80%" stop-color="#ef5b2b" />
<stop offset="80%" stop-color="#503969" />
<stop offset="90%" stop-color="#ab6294" />
<stop offset="90%" stop-color="#1cb98f" />
<stop offset="100%" stop-color="#48afc1" />
</radialGradient>
<!-- Маска -->
<mask id="msk1" >
<rect width="100%" height="100%" fill="black" />
<circle cx="300" cy="300" r="0" fill="white" >
<!-- Анимация маски прорезающей изображение дракончика и показывающее радиальный градиент -->
<animate attributeName="r" begin="svg1.click" dur="8s" values="0;300;300;0;0" fill="freeze" repeatCount="3" />
</circle>
</mask>
</defs>
<!-- Фоновое изображение радиальный градиент -->
<circle cx="300" cy="300" r="300" fill="url(#grad)" />
<image xlink:href="https://i.stack.imgur.com/6kywq.png" x="-140" y="-60" mask="url(#msk1)" width="800" height="780" />
</svg>
Не знаю почему этого ответа еще не было, можно сделать дырку в clip-path вот так:
let precision = 64;
let radius = 25;
let c = [...Array(precision)].map((_, i) => {
let a = -i/(precision-1)*Math.PI*2;
let x = Math.cos(a)*radius + 50;
let y = Math.sin(a)*radius + 50;
return `${x}% ${y}%`
})
document.querySelector('div').style.clipPath =
`polygon(100% 50%, 100% 100%, 0 100%, 0 0, 100% 0, 100% 50%, ${c.join(',')})`;
body {
background: url(https://picsum.photos/200/200)
}
div {
background: blue;
width: 200px;
height: 200px;
}
<div></div>
Я сгенерировал это кодом, однако можно просто вставить результирующий стиль:
div {
background: blue;
width: 200px;
height: 200px;
}
body {
background: url(https://picsum.photos/200/200)
}
<div style="clip-path: polygon(100% 50%, 100% 100%, 0px 100%, 0px 0px, 100% 0px, 100% 50%, 75% 50%, 74.8758% 47.5108%, 74.5043% 45.0463%, 73.8893% 42.6311%, 73.0369% 40.2891%, 71.9555% 38.0437%, 70.656% 35.917%, 69.1511% 33.9303%, 67.4559% 32.1033%, 65.5872% 30.4542%, 63.5637% 28.9994%, 61.4053% 27.7532%, 59.1335% 26.7282%, 56.771% 25.9344%, 54.3412% 25.3798%, 51.8683% 25.0699%, 49.3767% 25.0078%, 46.8914% 25.194%, 44.437% 25.6268%, 42.0378% 26.3018%, 39.7178% 27.2124%, 37.5% 28.3494%, 35.4064% 29.7015%, 33.4579% 31.2555%, 31.6737% 32.9957%, 30.0717% 34.9049%, 28.6677% 36.9641%, 27.4758% 39.1529%, 26.5077% 41.4495%, 25.7731% 43.8311%, 25.2792% 46.2739%, 25.0311% 48.7539%, 25.0311% 51.2461%, 25.2792% 53.7261%, 25.7731% 56.1689%, 26.5077% 58.5505%, 27.4758% 60.8471%, 28.6677% 63.0359%, 30.0717% 65.0951%, 31.6737% 67.0043%, 33.4579% 68.7445%, 35.4064% 70.2985%, 37.5% 71.6506%, 39.7178% 72.7876%, 42.0378% 73.6982%, 44.437% 74.3732%, 46.8914% 74.806%, 49.3767% 74.9922%, 51.8683% 74.9301%, 54.3412% 74.6202%, 56.771% 74.0656%, 59.1335% 73.2718%, 61.4053% 72.2468%, 63.5637% 71.0006%, 65.5872% 69.5458%, 67.4559% 67.8967%, 69.1511% 66.0697%, 70.656% 64.083%, 71.9555% 61.9563%, 73.0369% 59.7109%, 73.8893% 57.3689%, 74.5043% 54.9537%, 74.8758% 52.4892%, 75% 50%);"></div>
