Una completa guía para el recortar y enmascarar con SVG
Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)
Recortar y enmascarar es una característica de SVG que tiene la capacidad de ocultar total o parcialmente partes de un objeto mediante el uso de formas simples o complejas. A lo largo de los años, muchos desarrolladores han tomado estas capacidades y las han llevado más allá en varias direcciones. En este artículo vamos a echar un vistazo a algunos métodos avanzados junto con demos que ejemplifican el recorte y el enmascaramiento consiguiendo un gran efecto. ¡Empecemos!
¿Qué es recortar? ¿Qué es enmascarar?
Vamos a responder primero esta pregunta: ¿cuál es la diferencia entre recortar y el enmascarar? Vamos a echar un vistazo a cada uno para obtener una mejor comprensión. Ten en cuenta que si bien la mayoría de las características descritas en la especificación funcionan hoy en día, otras no lo harán. Compruébalo minuciosamente siempre en caniuse, y realiza también tus propias pruebas en el navegador.
Recortar
Un trazado de recorte es un objeto en donde todo lo que está dentro de la forma definida queda visible, mientras que la parte exterior está "recortada" y no aparecerá en el lienzo



En la imagen de muestra anterior, nuestra forma (el logotipo de Envato) es el objeto que usaremos como nuestro objeto de trazado para el recorte. El resultado se recorta del fondo sólido dejando sólo una forma con perfiles definidos igual a nuestra "región de recorte".
Enmascarar
Aquí tomamos un objeto gráfico o forma que se pintará sobre el fondo a través de una máscara, enmascarando así total o parcialmente partes del objeto.



Piensa en las máscaras como una forma de aceptar la región visible que se ha definido previamente mediante la forma de un objeto. En este escenario nuestra máscara es el objeto que deseamos "extraer" de nuestro fondo de color sólido. El resultado es una forma idéntica a nuestra máscara (es decir, la forma negra sólida).
La diferencia
¿Sigues confundido en cuanto a cuál es la diferencia? Existe una muy sutil distinción entre estos dos tipos de opciones. Concibe un trazado de recorte como una "máscara dura" donde el objeto delimitador eliminado es una forma que no presenta píxeles transparentes u opacos. Una máscara consiste en una forma o imagen donde cada píxel tiene diferentes grados de transparencia y opacidad a través de los que se puede mostrar, u ocultar partes de una manera muy sutil.
Ahora vamos a ver algunos elementos y atributos que permiten el recorte y el enmascaramiento con SVG.
clipPath
El clipPath de un SVG acepta muchos atributos y tipos de modelo de contenido. Los tipos de modelos de contenido aceptados son, por ejemplo title y description, además de otros tipos de etiquetas de metadatos. También acepta etiquetas de animación SMIL como <animate>, <animateTransform>, formas SVG (circle, rect, polygon, path) incluyendo <text>, <use>, style y <script>. Incluso puedes tener varias definiciones clipPath dentro de un clipPath pardre.
Aquí tienes un fragmento de código con metaetiquetas, SMIL y formas SVG:
1 |
<svg viewBox="0 0 100 100" xmlns="https://www.w3.org/2000/svg" version="1.1"> |
2 |
<defs>
|
3 |
<clipPath id="my-clip"> |
4 |
<title>My Clip Path</title> |
5 |
<desc>an svg rectangle using a circle as the clipping target and animated with SMIL</desc> |
6 |
<rect x="0" y="0" width="200" height="600"> |
7 |
<animate attributeType="XML" |
8 |
attributeName="x" |
9 |
from=“-200" |
10 |
to=“400" |
11 |
dur="5s" |
12 |
repeatCount="indefinite"/> |
13 |
</rect>
|
14 |
</clipPath>
|
15 |
</defs>
|
16 |
|
17 |
<circle clip-path="url(#my-clip)" width="200" height="200" cx="50" r="50" cy="50" fill="green" /> |
18 |
</svg>
|
También se puede hacer referencia a un clipPath creado en SVG desde CSS mediante la propiedad clip-path de la siguiente manera:
1 |
.element { |
2 |
clip-path: url("#my-clip"); |
3 |
}
|
Aquí estoy haciendo referencia al clip de nuestro fragmento SVG anterior con la función url(), y pasando el valor id de nuestro clipPath. También existe la opción de usar imágenes como destino de un clipPath:
1 |
<svg viewBox="0 0 200 300"> |
2 |
<defs>
|
3 |
<clipPath id="clip"> |
4 |
<style>
|
5 |
circle {
|
6 |
fill: black; |
7 |
} |
8 |
</style>
|
9 |
<circle cx="100" cy="100" r="100"/> |
10 |
</clipPath>
|
11 |
</defs>
|
12 |
|
13 |
<image height="100%" preserveAspectRatio="xMinYMin slice" width"100%" xlink:href="https://images.unsplash.com/photo-1472195870936-d88b0d4c1b41?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=f1abbd4d59a9b448813cb48769806ada" clip-path="url(#clip)" /> |
14 |
</svg>
|
La imagen de este fragmento está utilizando una forma SVG (circle) como su objeto de recorte. El resultado es un círculo con una imagen dentro de él; muy elegante ¿no? También puedes observar la inclusión de la etiqueta style en clipPath. Cualquier etiqueta <style> situada dentro de clipPath (o mask) prevalecerá sobre cualquier atributo relacionado, y CSS externo.
Atributos clipPath
Hay varios atributos que clipPath puede aceptar y, sin duda, demasiados para enumerarlos. Los atributos concretos clipPath dignos de mención en este artículo son clipPathUnits y clip-rule. Aquí tienes un listado que describe lo que hace cada uno y cómo elegir los valores adecuados.
clipPathUnits
Este atributo es extremadamente importante, ya que ayuda a definir el "sistema de coordenadas" o, en otras palabras, la "ubicación" de los contenidos de clipPath. Acepta dos tipos de valores, pero solo se puede pasar uno. De forma predeterminada, se toma userSpaceOnUse que es el que usarás normalmente.
-
userSpaceOnUseLos contenidos declipPathrepresentan valores en el sistema de coordenadas del usuario existentes justo cuando se hace referencia al elementoclipPath, en otras palabras, el sistema de coordenadas del usuario para el elemento tomando como referencia elclipPatha través de la ruta de acceso de la propiedadclip-path. -
objectBoundingBoxEl sistema de coordenadas tiene su origen en la esquina superior izquierda del cuadro delimitador del elemento al que se aplica el trazado de recorte y el mismo ancho y alto que este cuadro delimitador. Las coordenadas de usuario se miden en equivalencia con la unidad CSSpx.
clip-rule
clip-rule es otro importante atributo, pero también es bastante complicado de comprender correctamente y se encuentra dentro de los "atributos de presentación" de clipPath. Este atributo solo se aplica a los elementos gráficos contenidos en un elemento clipPath. Cuando se combina con la propiedad clip-path, define qué regla de recorte o algoritmo se debe usar al rellenar las diferentes partes de un gráfico. También se puede conseguir mediante el uso de la regla de relleno fill-rule.
clip-rule se puede colocar en un clipPath, al que se referencia desde el archivo CSS o en los estilos SVG en línea. La regla fill-rule también se puede colocar en el destino del objeto de recorte, pero cada una de las opciones tendrá un resultado muy diferente.
-
nonzero: este valor define si un punto está dentro o fuera del trazado dibujando una línea desde un punto inicial hacia el infinito en cualquier dirección y contando los lugares en donde un segmento de una forma cruza la línea en una dirección específica. Cuando un segmento cruza la línea de izquierda a derecha, el recuento se incrementa; cuando un segmento cruza la línea de derecha a izquierda, el recuento se reduce. Si el recuento es cero, el punto está fuera; si no es cero, está dentro. -
evenodd: este valor define si un punto está dentro o fuera del trazado dibujando una línea desde ese punto hacia el infinito en cualquier dirección y contando el número de segmentos de forma que cruza la línea. Si el recuento es impar, el punto está dentro; si es par, el punto está fuera.
Máscara
Una máscara puede hacer un montón de cosas increíbles con imágenes, formas, bordes, y posicionarlo todo a través del uso de <mask>. Aunque posee la capacidad de definirse dentro de un SVG, también se puede hacer referencia a ella con CSS a través de la propiedad mask. Una máscara puede aceptar un clipPath, u otra mask (hola orígenes). Se aceptan diferentes tipos de modelos de contenido, listados en su totalidad en la especificación W3C.
Este es un ejemplo de código que usa formas SVG como objetos de enmascaramiento y tiene como destino una imagen SVG en línea.
1 |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> |
2 |
<defs>
|
3 |
<mask id="image-mask"> |
4 |
<circle id="outer" cx="50" cy="50" r="50" fill="white"/> |
5 |
<circle id="inner" cx="50" cy="50" r="25"/> |
6 |
</mask>
|
7 |
</defs>
|
8 |
<image width="100%" height="100%" preserveAspectRatio="xMidYMid slice" xlink:href="https://images.unsplash.com/photo-1472195870936-d88b0d4c1b41?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ%3D%3D&s=f1abbd4d59a9b448813cb48769806ada" mask="url(#image-mask)"></image> |
9 |
</svg>
|
Este ejemplo de código da como resultado una rosquilla donde el círculo interior es transparente y el anillo exterior permite que la imagen se muestre a través. Hay una demostración completa al final de este artículo que muestra el resultado.
1 |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> |
2 |
<defs>
|
3 |
<mask id="SVGMask" mask-type="luminance" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"> |
4 |
<style>
|
5 |
#rect { |
6 |
mask-image: url(#SVGMask); |
7 |
mask-mode: luminance; |
8 |
}
|
9 |
</style>
|
10 |
<radialGradient id="radialFill"> |
11 |
<stop stop-color="white" offset="0"/> |
12 |
<stop stop-color="black" offset="1"/> |
13 |
</radialGradient>
|
14 |
<circle fill="url(#radialFill)" cx="0.5" cy="0.5" r="0.5"/> |
15 |
</mask>
|
16 |
</defs>
|
17 |
<rect id="rect" width="100" height="100" fill="green"/> |
18 |
</svg>
|
Aquí hay otro fragmento de código donde uso propiedades CSS como estilos en línea anidados dentro de mask para hacer referencia a nuestro objeto de enmascaramiento, y controlar la iluminación usando luminancia (la intensidad de la luz emitida por la superficie).
mask-image
Hay un par de maneras en las que los autores pueden definir una máscara SVG. La primera es a través del uso del atributo SVG mask="url(#id-value)" normalmente definido en el destino de la mascara que está dentro de tu SVG, y el otro es mask-image.
Al igual que mask, la propiedad mask-image acepta un identificador como valor del ID de máscara utilizado en el fragmento de código anterior. Si se utiliza dentro del CSS, puedes hacer referencia al propio archivo SVG a través de la función de url mask-image: url(your-external-file.svg#the-mask-id-value).
mask-mode
Esta propiedad determina si la máscara se trata como una máscara de luminancia o una máscara alfa. El valor de alpha controla el grado de transparencia que permite la máscara, y un valor luminance controla la intensidad de la luz emitida. Si decides definir esto como un atributo en tu máscara SVG, puedes utilizar el atributo mask-type directamente en el elemento SVG mask, o también puedes utilizar mask-mode para definirlo dentro de CSS.
maskUnits
1 |
<mask maskUnits="[objectBoundingBox | userSpaceOnUse]"> |
Al igual que clipPathUnits, mask tiene un atributo muy similar. Este atributo de enmascaramiento ayuda a definir el sistema de coordenadas para atributos como x, y, width y height. Si no hay ningún valor presente, se utiliza un valor de objectBoundingBox de forma predeterminada.
-
userSpaceOnUse: el sistema de coordenadas del usuario para el elemento que referencie la<mask> -
objectBoundingBox: un cuadro delimitador podría considerarse igual que si el contenido de<mask>estuviera delimitado por una ventana de visualización "0 0 1 1".
maskContentUnits
1 |
<mask maskContentUnits="[objectBoundingBox | userSpaceOnUse]"> |
Define el sistema de coordenadas para el contenido de la máscara. Al igual que maskUnits, también acepta userSpaceOnUse o objectBoundingBox como valor. Si no se pasa ninguno, se utiliza un valor de userSpaceOnUse de forma predeterminada.
-
userSpaceOnUse: el sistema de coordenadas del usuario para el elemento al que hace referencia<mask> -
objectBoundingBox: un cuadro delimitador podría considerarse igual que si el contenido de<mask>estuviera delimitado por una ventana de visualizaciónviewbox "0 0 1 1".
Casos de uso
En la actualidad hay unas cuantas maneras muy inteligentes de implementar máscaras y trazados de recorte en tu trabajo.
Demostración 1
Este es un ejemplo usado en el contexto de un esquema de carga lenta, en donde proporcionamos al usuario una sensación de carga percibida del contenido (pulsa rerun en la esquina inferior derecha para ver el efecto).
Una vez obtenidos los datos de la API, podemos empezar a desplegar contenido. Esto combina el uso de degradados CSS, animación CSS y SVG clipPath. Gracias al creador original Yacine que inspiró mi actualizada demo de arriba. Debo señalar que para ir en esta dirección tendrás que volver a crear el aspecto del marcador de posición de tu producto final utilizando un editor SVG como Sketch para crear la estructura inicial.
Demostración 2
Aquí hay otro enfoque inteligente y artístico, tomado de un pen de Noel Delgado, que muestra eventos flotantes usando recorte SVG:
Si bien se utiliza JavaScript para detectar la posición del ratón, el efecto en sí es de hecho un clipPath SVG. Un efecto maravilloso para las secciones de un portafolio que muestra el trabajo, sin embargo, asegúrate de crear alternativas para escenarios en los que un ratón no esté presente.
Demostración 3
Descubrí este efecto utilizado en horizon.io hace siglos (ya no existe) y logré trasladarlo a una demostración en CodePen.
Es un enfoque muy inventivo empleando clipPath y algo de movimiento con el fin de mostrar cómo un diseño es transferido de un dispositivo a otro.
Demostración 4
A veces lo simple es tan eficaz como lo complejo. Soy un gran fan de la tipografía y en este ejemplo de Steven Sinatra se utiliza una máscara SVG para ayudar a aislar el texto y animarlo en su lugar (de nuevo, tendrá que pulsar rerun). Un enfoque divertido que se puede utilizar para esas famosas secciones "hero".
Demostración 5
Elegí este pen porque es un caso de uso realmente genial para rellenar iconos en escenarios como calificaciones o en los enlaces de entradas/elementos, y todo se consigue con una máscara SVG.
Demostración 6
Originalmente creado por Dudley Storey, este fork de Shaw utiliza una máscara SVG para aislar a cada skater al situar sobre ellos el cursor. Con el ratón, pasa el cursor sobre cada uno para ver el efecto que tiene lugar. Bastante guay, ¿eh?
¿Quieres más?
¿Qué tal algo sólo por diversión? Los carteles de películas son actualmente más cool gracias a Chase. Un ejemplo de uso muy divertido y creativo de máscaras SVG, ¡y también de filtros!
También he creado una demo pública que contiene más ejemplos que muestran cómo configurar diferentes tipos de clips y máscaras mediante una combinación de escenarios, acompañados de muestras adicionales con SMIL.
Últimas reflexiones
Ahí lo tienes; un resumen y análisis sobre el recorte y el enmascaramiento en SVG. ¿Estás empleando este tipo de enfoques actualmente en tu trabajo? ¿Tienes una muestra de algún caso de excelente uso para compartir, o simplemente, tienes alguna opinión general sobre las cosas que hemos visto? ¡Publica tus comentarios a continuación y feliz disfruta creando código!
Recursos


SVGCómo crear un SVG a mano con códigoKezz Bracey

SVGNuevo curso: Cambiar de iconos de fuente a SVGAndrew Blackman

SVGBrillantez SVG: 10 inspiradores ejemplos de toda la webDennis Gaebel

SVGSVG para diseñadores web en 60 segundosKezz Bracey
- Enmascaramiento CSS en W3C
- Lenguaje de integración multimedia sincronizado (SMIL) en W3C
- El elemento 'animateTransform' en W3C
- SVG en Envato Tuts+
- Animar elementos animados en SVG en Smashing Magazine
- Usar clip-path SVG para cambiar el color de un logotipo durante el desplazamiento
- Efectos hover con SVG clipPath en tympanus.net



