Máscaras con mask

facebook-svg gplus-svg twitter-svg

Una mascara según wordreference.com es una pieza de cartón, tela, etc..., para taparse la cara y no ser conocido o para protegerse de algo. En SVG una máscara es todo lo contrario. La única región visible es la que se encuentra debajo de la máscara.

Exactamente como <clipPath> las mascaras limitan la zona donde un objeto svg es pintado encima del llienzo SVG.

A diferencia de <clipPath>

A diferencia de <clipPath> que utiliza vectores para recortar un objeto SVG, una mascara <mask> es como una imagen donde los pixeles son translucidos con valores que van de totalmente transparente a totalmente opaco.

Un elemento <mask> es un contenedor para cualquier tipo de elementos svg, incluso grupos <g> símbolos <symbol> e imágenes, elementos que no pueden aparecer dentro de <clipPath>.

Un ejemplo básico

En el siguiente ejemplo un rectángulo verde cubre todo el lienzo SVG. Solo una porción de este rectángulo es visible: la zona que se encuentra debajo de la máscara.
Miremos de cerca el código. Utilizamos el elemento <mask> para definir una máscara. Anidado dentro del elemento <mask> aparece el trazado que queremos utilizar como máscara: en este caso otro rectángulo.

<mask id="mascara">
   <rect x="50" y="50" width="150" height="100" style="stroke:none; fill: #ffffff"></rect> 
</mask>

El relleno del rectángulo es blanco: fill = "#ffffff". Esto es muy importante y veremos más tarde por que. Como siempre cuando se trata de un elemento que no aparece en pantalla, ponemos el elemento <mask> dentro de un elemento <defs> ( definiciones ).
A continuación dibujamos un rectángulo verde al cual le aplicamos la máscara definida anteriormente:

<rect width="250" height="200" fill="#6ab150" style="mask:url(#mascara)"/>



  
    
  


Que pasa con el color de relleno

En el siguiente ejemplo la máscara <mask id="colorDeRelleno"> contiene 9 elementos <circle> cuyo color de relleno toma varios valores de grises. Observamos que el color de relleno determina el valor alpha o la transparencia de la máscara. Si el color de relleno es blanco fill="#ffffff", la máscara es totalmente transparente. Si el color de relleno es negro fill="#000000", la máscara es totalmente opaca. Los diferentes grises determinan diferentes niveles de transparencia de la máscara.



 
  
    
    
    
		
    
    
    
		
    
    
    
  
 

 
	
 #ffffff
 #cccccc
 #aaaaaa
 #999999
 #777777
 #555555
 #333333
 #111111
 #000000
#ffffff #cccccc #aaaaaa #999999 #777777 #555555 #333333 #111111 #000000

Que pasa con la opacidad del color de relleno

El siguiente ejemplo es una replica del ejemplo anterior. Todos los círculos tienen el color de relleno blanco: fill="#ffffff" pero la opacidad del relleno varia de 100%, o sea totalmente opaco ( fill-opacity= "1" ) a 0% o totalmente transparente ( fill-opacity= "0" ).  Observamos que si el relleno del circulo es totalmente opaco ( 100% ) la máscara generada es totalmente transparente, y si el relleno del circulo es totalmente transparente ( 0% ) la máscara generada es totalmente opaca.



 
  
    
    
    
		
    
    
    
		
    
    
    
  
 

 
	
 100%
 90%
 75%
 60%
 50%
 40%
 25%
 10%
 0%
100% 90% 75% 60% 50% 40% 25% 10% 0%

Un caso concreto

En el siguiente ejemplo queremos recortar solo la imagen del madroño y queremos que los bordes estén suavizados, casi desvanecidos.
Para esto la máscara <mask id= "maskCirculo" > contiene un círculo cuyo relleno fill utiliza un degradado radial fill="url(#degradadoRadial)". El degradado va de blanco ( en el centro ) a negro. Sabemos que el blanco genera una máscara totalmente transparente mientras que el negro genera una máscara totalmente opaca, por lo cual la máscara será totalmente transparente en el centro cambiando gradualmente a opaca en el borde.



 
  
   
   
  
  
   
  
 

Crear un agujero con <mask>

Para crear un agujero dentro de un elemento <mask>; svg voy a colocar un rectángulo blanco que cubra totalmente el objeto a perforar. Encima de este rectángulo blanco voy a dibujar un circulo negro (el agujero). Debajo de los pixeles blancos la mascara será totalmente transparente y el objeto será visible mientras que debajo de los pixeles negros el objeto no será pintado dejando visible lo que puede haber debajo del objeto – en este caso el fondo anaranjado del elemento svg.

<svg viewBox="0 0 300 300" width="300">
 <mask id="mask">
   <rect width="300" height="300" fill="white"/>
   <circle cx="150" cy="150" r="90" fill="black"/>
 </mask>
 <image width="300" height="300" xlink:href="img.jpg" mask="url(#mask)"/> 
</svg>

See the Pen crear un agujero con mask*** by Gabi (@enxaneta) on CodePen.

Atributos específicos de mask

El id es el único atributo imprescindible del elemento <mask> ya que se utiliza para referenciarlo mas tarde:

<mask id="el_id" >
       <circle cx="120" cy="125" r="70"></circle>
</mask>
<image xlink:href="img.jpg" mask="url(#el_id)" height="240" width="250" ></image>

Además del id podemos utilizar varios atributos presentacionales entre los cuales cabe destacar: maskUnits y maskContentUnits.
El atributo maskUnits controla el tamaño de la mascara mientras que maskContentUnits controla el tamaño de los elementos contenidos por la mascara
Estos atributos pueden tomar uno de estos dos valores: userSpaceOnUse o objectBoundingBox.
El valor por defecto de estos dos atributos es:

maskUnits = "userSpaceOnUse"
maskContentUnits = "objectBoundingBox"

El sistema de coordenadas de referencia para objectBoundingBox es un cuadrado de 1x1 con el origen en la esquina superior izquierda, y es redimensionado para llenar la caja delimitadora del objeto SVG al cual aplicamos la mascara.

Por ejemplo si maskUnits = objectBoundingBox podemos utilizar una mascara de este tipo:

<mask id="obb-usou" maskUnits="objectBoundingBox"
      x="0.1" y="0.1"
      width="0.5" height="0.5">
      . . . . . .

En este caso el origen de la mascara se encuentra a 10% de la esquina superior izquierda y anchura de la mascara es de 50% de la anchura del objeto SVG al cual aplicamos la mascara.

Si maskUnits="userSpaceOnUse" necesitamos conocer el tamaño y la posición del objeto svg al cual la aplicamos. Por ejemplo si este objeto es un rectángulo

<rect x="0" y="0" width="100" height="100"/>

la mascara anterior podría tener este aspecto:

<mask id="usou-usou" maskUnits="userSpaceOnUse"
      x="10" y="10"
      width="50" height="50" >
      . . . . . .

Este es un ejemplo donde puede entender el uso de los atributos maskUnits y maskContentUnits.

See the Pen svg mask1 by Gabi (@enxaneta) on CodePen.