Máscara SVG o estilo CSS para eliminar el centro de svg para que sea transparente
Tengo un SVG que es esencialmente un cuadro con bordes redondeados y bordes en las esquinas de cada borde:
<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>
Se coloca sobre un contenedor div con un fondo de color:
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;
}
Quiero que el centro del SVG (toda el área central dentro de los bordes con bordes blancos) sea transparente. Entonces, en este ejemplo, verá el fondo blanco del cuerpo.
Aquí hay un CodePen: https://codepen.io/lance-p/pen/mdrwyyN
Me dijeron que podría usar una máscara para lograr esto, pero no he podido hacer que funcione. ¡Cualquier sugerencia (con o sin máscara) será apreciada!
Respuestas
Esta es una solución alternativa en la que estoy usando una sombra muy amplia en lugar del .container
fondo.
También he simplificado el svg, pero puedes mantener tu código aquí.
*{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 está comentando:
De alguna manera puede resaltar en la descripción la solución principal para colocar las esquinas blancas stroke-dasharray = "80168" stroke-dashoffset = "58"
Primero necesitas saber la longitud total del rectángulo con esquinas redondeadas. let l = r.getTotalLength();
. Divide este valor entre 4 para conocer el total de un trazo y un espacio: let stroke_gap = l/4;
A continuación, elige un valor para el trazo, por ejemplo let stroke = 80
. Para el espacio que usarás let gap = stroke_gap - stroke;
, redondeé los números. Quizás no debería. Esto me está dando algo como stroke-dasharray="80 168"
Si está usando solo esto, el primer trazo comenzará a una distancia de 20 unidades (rx = "20") desde la esquina (x = "1" y = "1") Necesitará un stroke-dashoffset
para compensar los trazos y hacerlos doblados alrededor de las esquinas.
Puede calcular la longitud de la parte de la esquina del camino: es la longitud de 1/4 del perímetro de un círculo con radio = 20 (rx = 20): let corner = 2 * Math.PI * radius/4;
el valor para el desplazamiento del trazo-tablero debe serlet 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>