Tengo un SVG con un fondo degradado y un ícono en primer plano. Actualmente, el ícono es solo una ruta rellena con polilíneas en la parte superior, pero puede dividirse en múltiples rutas donde la polilínea sería el trazo. Sin embargo, quiero que, en lugar de que la polilínea o el trazo tengan un color, muestren el fondo, como si hubiera hecho un agujero en el primer plano. Debido a que el fondo es un degradado (en realidad es un filtro de sombras) y no un color sólido, no puedo simplemente tener un trazo con el mismo color que el fondo para hacer esto. Esto es lo que imagino que sería el resultado si pudiera tener un ancho de trazo negativo en las múltiples rutas.
Como ejemplo, usaré el SVG que realmente es para (mi foto de perfil). Entonces, este es mi código SVG actual.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" stroke="black" fill="rgb(95,95,95)" viewBox="-30 -30 276 260" width="276" height="260" stroke-width="4"> <defs> <filter id="shadow" x="-30" y="-30" width="276" height="260"> <feGaussianBlur in="SourceAlpha" out="blurOut" stdDeviation="32"/> <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/> </filter> </defs> <rect x="-30" y="-30" width="276" height="260" fill="#c41313" stroke="none"/> <path d="M108 0 L216 54 L216 103 L162 130 L162 152 L135 166 L135 187 L108 200 L82 187 L82 166 L54 152 L54 130 L0 103 L0 54 Z" filter="url(#shadow)"/> <g fill="none"> <polyline points="82 166, 108 179, 135 166"/> <polyline points="54 130, 108 157, 162 130"/> <polyline points="0 54, 108 108, 216 54"/> <polyline points="49 78.5, 108 49, 167 78.5"/> <line x1="108" y1="0" x2="108" y2="49"/> <line x1="108" y1="200" x2="108" y2="108"/> </g> </svg>Un enfoque más convencional sería usar una <mask> :
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 276 260" width="276" height="260"> <defs> <mask id="mask" stroke-width="4" stroke="#000"> <g transform="translate(30 30)"> <path id="shapeBG" d="M108 0 L216 54 L216 103 L162 130 L162 152 L135 166 L135 187 L108 200 L82 187 L82 166 L54 152 L54 130 L0 103 L0 54 Z" fill="#fff" /> <g fill="none"> <polyline points="82 166, 108 179, 135 166" /> <polyline points="54 130, 108 157, 162 130" /> <polyline points="0 54, 108 108, 216 54" /> <polyline points="49 78.5, 108 49, 167 78.5" /> <line x1="108" y1="0" x2="108" y2="49" /> <line x1="108" y1="200" x2="108" y2="108" /> </g> </g> </mask> <filter id="shadow" x="0" y="0" width="276" height="260"> <feGaussianBlur in="SourceAlpha" out="blurOut" stdDeviation="32" /> <feBlend in="SourceGraphic" in2="blurOut" mode="normal" /> </filter> </defs> <rect id="bg" x="0" y="0" width="100%" height="100%" fill="#c41313" stroke="none" /> <g filter="url(#shadow)"> <rect x="0" y="0" width="100%" height="100%" mask="url(#mask)" fill="rgb(95,95,95)" /> </g> </svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="-30 -30 276 260" width="276" height="260"> <g id="mask" stroke-width="4" stroke="#000"> <path id="shapeBG" d="M108 0 L216 54 L216 103 L162 130 L162 152 L135 166 L135 187 L108 200 L82 187 L82 166 L54 152 L54 130 L0 103 L0 54 Z" fill="#fff" /> <g fill="none"> <polyline points="82 166, 108 179, 135 166" /> <polyline points="54 130, 108 157, 162 130" /> <polyline points="0 54, 108 108, 216 54" /> <polyline points="49 78.5, 108 49, 167 78.5" /> <line x1="108" y1="0" x2="108" y2="49" /> <line x1="108" y1="200" x2="108" y2="108" /> </g> <text style="font-size:11; font-family:Arial, sans-serif" stroke-width="0" x="0" y="80%" dominant-baseline="middle">Mask: white fills/strokes=opaque; <tspan x="0" dy="12">black fills/strokes=transparent<tspan></text> </svg>A la derecha se ve el gráfico de la máscara real:
<mask> también podría usarse para obtener trazos semitransparentes, por ejemplo, configurando el color del trazo en algo como rgb(128,128,128) .
Con respecto al soporte de software, también puede realinear sus gráficos a través de una transformación para evitar valores negativos de viewBox : algunos editores tienen problemas con estos.
El usode CSS mix-blend-mode parece lograr lo que desea, aunque todavía no estoy seguro de cómo arreglar el gris y la sombra:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" stroke="black" fill="rgb(95,95,95)" viewBox="-30 -30 276 260" width="276" height="260" stroke-width="4"> <defs> <filter id="shadow" x="-30" y="-30" width="276" height="260"> <feGaussianBlur in="SourceAlpha" out="blurOut" stdDeviation="32"/> <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/> </filter> </defs> <rect x="-30" y="-30" width="276" height="260" fill="#c41313" stroke="none"/> <g stroke="black" style="mix-blend-mode: color-dodge;"> <path d="M108 0 L216 54 L216 103 L162 130 L162 152 L135 166 L135 187 L108 200 L82 187 L82 166 L54 152 L54 130 L0 103 L0 54 Z" filter="url(#shadow)"/> <g fill="none"> <polyline points="82 166, 108 179, 135 166"/> <polyline points="54 130, 108 157, 162 130"/> <polyline points="0 54, 108 108, 216 54"/> <polyline points="49 78.5, 108 49, 167 78.5"/> <line x1="108" y1="0" x2="108" y2="49"/> <line x1="108" y1="200" x2="108" y2="108"/> </g> </g> </svg>Puede hacer esto en un solo filtro con una técnica de pantalla verde. Haces que las líneas exteriores e interiores sean de color azul y verde puros y luego usas ColorMatrix para seleccionarlas en capas separadas y luego componerlas o sacarlas de la forma original. Es importante usar shape-rendering=crispEdges porque hay artefactos de suavizado que se ven mal si no lo hace.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-30 -30 276 260" width="276" height="260" stroke-width="4" color-interpolation-filters="sRGB" shape-rendering="crispEdges"> <defs> <filter id="green-screen" x="-30" y="-30" width="276" height="260"> <feColorMatrix type="matrix" values="0 0 0 0 0 0 2 0 0 -1 0 0 0 0 0 -1 2 -1 0 -1" result="exterior-line"/> <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 2 0 -1 -1 -1 2 0 -1" result="interior-line"/> <feComposite operator="out" in="SourceGraphic" in2="exterior-line"/> <feComposite operator="out" in2="interior-line" result="masked-shape"/> <feGaussianBlur in="SourceAlpha" out="blurOut" stdDeviation="32"/> <feComposite operator="over" in="masked-shape"/> </filter> </defs> <rect x="-30" y="-30" width="276" height="260" fill="#c41313"/> <g filter="url(#green-screen)"> <path d="M108 0 L216 54 L216 103 L162 130 L162 152 L135 166 L135 187 L108 200 L82 187 L82 166 L54 152 L54 130 L0 103 L0 54 Z" fill="rgb(95,95,95)" stroke="rgb(0,255,0)"/> <g fill="none" stroke="rgb(0,0,255)"> <polyline points="82 166, 108 179, 135 166"/> <polyline points="54 130, 108 157, 162 130"/> <polyline points="0 54, 108 108, 216 54"/> <polyline points="49 78.5, 108 49, 167 78.5"/> <line x1="108" y1="0" x2="108" y2="49"/> <line x1="108" y1="200" x2="108" y2="108"/> </g> </g> </svg>