Maska SVG lub styl CSS, aby wyciąć środek SVG, aby był przezroczysty
Mam plik SVG, który jest zasadniczo pudełkiem z zaokrąglonymi krawędziami i obramowaniami w rogach każdej krawędzi:
<div class="container">
</div>
<svg width="258" height="258" viewBox="0 0 258 258" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M257 211.489L257 245C257 251.627 251.627 257 245 257L211.489 257" stroke="white" stroke-width="2" />
<path d="M211.489 0.999998L245 0.999999C251.627 1 257 6.37258 257 13L257 46.5111" stroke="white" stroke-width="2" />
<path d="M46.5111 257L13 257C6.37258 257 1 251.627 1 245L1.00001 211.489" stroke="white" stroke-width="2" />
<path d="M1 46.5111V13C1 6.37258 6.37258 1 13 1H46.5111" stroke="white" stroke-width="2" />
</svg>
Jest umieszczony nad elementem div kontenera z kolorowym tłem:
body{background: white}
.container {
margin-top: 70px;
height: 400px;
margin: 0 auto;
background-color: black;
opacity: 0.55;
}
svg {
position: absolute;
top: 50px;
left: 300px;
}
Chcę, aby środek SVG (cały środkowy obszar wewnątrz białych krawędzi) był przezroczysty. W tym przykładzie zobaczysz białe tło ciała.
Oto CodePen tego: https://codepen.io/lance-p/pen/mdrwyyN
Powiedziano mi, że mogę użyć maski, aby to osiągnąć, ale nie udało mi się zmusić jej do działania. Wszelkie sugestie (z maską lub bez) będą mile widziane!
Odpowiedzi
To alternatywne rozwiązanie, w którym zamiast .container
tła używam bardzo szerokiego cienia .
Uprościłem również svg, ale możesz zachować tutaj swój kod.
*{margin:0;padding:0}
body {
background: white;
}
.container {
margin-top: 70px;
height: 400px;
margin: 0 auto;
overflow: hidden;
opacity: 0.55;
}
#hole {/*I want the hole to be slightly smaller than the svg element hence the calc*/
width:calc(258px - 8px);
height:calc(258px - 8px);
border-radius:20px;
position: relative;
top: calc(50px + 4px);
left: calc(300px + 4px);
background:transparent;
box-shadow:0 0 0 200vmax #000;
}
svg{
width:258px;
height:258px;
position: absolute;
top: 50px;
left: 300px;
}
<div class="container">
<div id="hole"></div>
</div>
<svg width="258" height="258" viewBox="0 0 258 258" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="256" height="256" rx="20" id="r" stroke="white" stroke-width="2" stroke-dasharray="80 168" stroke-dashoffset="58" fill="none" />
</svg>
@alexandr_TT komentuje:
Można w jakiś sposób wyróżnić w opisie główne rozwiązanie dotyczące umieszczania białych rogów stroke-dasharray = "80 168" stroke-dashoffset = "58"
Najpierw musisz znać całkowitą długość prostokąta z zaokrąglonymi narożnikami. let l = r.getTotalLength();
. Dzielisz tę wartość przez 4, aby poznać sumę pociągnięcia i przerwy: let stroke_gap = l/4;
Następnie wybierasz na przykład jedną wartość pociągnięcia let stroke = 80
. Dla luki, której użyjesz let gap = stroke_gap - stroke;
, zaokrągliłem liczby. Może nie powinienem. To daje mi coś w stylu stroke-dasharray="80 168"
Jeśli używasz tylko tego, pierwsze pociągnięcie rozpocznie się w odległości 20 jednostek (rx = "20") od rogu (x = "1" y = "1") Będziesz potrzebować stroke-dashoffset
do przesunąć pociągnięcia i wygiąć je wokół rogów.
Możesz obliczyć długość części narożnej ścieżki: Jest to długość 1/4 obwodu koła o promieniu = 20 (rx = 20): let corner = 2 * Math.PI * radius/4;
Wartość przesunięcia obrys-kreska powinna wynosićlet sdo = stroke/2 + corner/2
let l = r.getTotalLength();
let radius = 20;
let stroke_gap = l/4;
let stroke = 80;
let gap = stroke_gap - stroke;
let corner = 2 * Math.PI * radius/4;
let sdo = stroke/2 + corner/2;
r.setAttribute("stroke-dasharray",`${stroke} ${gap}`)
r.setAttribute("stroke-dashoffset",sdo)
<svg viewBox="0 0 258 258" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="256" height="256" rx="20" stroke="gold" stroke-width="5" fill="none" />
<rect x="1" y="1" width="256" height="256" rx="20" id="r" stroke="black" stroke-width="2" fill="none" />
<path d="M1,21A20 20 0 0 1 21,1" stroke="red" fill="none" id="corner" />
</svg>