Cosas pegajosas (goo)

facebook-svg gplus-svg twitter-svg

Quiero crear este efecto de elementos ( <div> ) pegajosos que se transforman y se funden uno con otro como las gotas de metal fundido. Vea este articulo en css-triks.com: the gooey effect.

Cosas pegajosas con CSS

Lo básico: en el HTML tenemos dos elementos <div class="pegajoso"> en un .contenedor.

<div class ="contenedor ">
  <div class="pegajoso">A</div>
  <div class="pegajoso">B</div>  
</div>

En pocas palabras: para que esto funcione:

1. el .contenedor tiene que ser blanco ( background-color:#fff; ) y los dos divs .pegajosos tienen que ser negros ( background-color:#000; ). O al revés. Lo importante aquí es el contraste.
También es importante que .contenedor sea bastante más grande, que haya un margen entre los elementos .pegajosos y el borde del contenedor. De lo contrario los elementos se funden con los bordes, y no es lo que queremos.

2. Aplicamos un desenfoque gaussiano al contenedor.

.contenedor{ filtro:blur(10px);}

3. Y a continuación aplicamos otro filtro para aumentar el contraste entre el fondo blanco y los elementos desenfocados.

.contenedor{ filtro:blur(10px) contrast(30);}

La imagen que se consigue tiene la claridad y la nitidez de la imagen original, pero los dos elementos .pegajosos aparecen fundidos.

See the Pen GOO #1 CSS by Gabi (@enxaneta) on CodePen.

Esto está muy bien pero no demasiado útil. De entrada cualquier cosa que podamos escribir en los div .pegajosos aparecerá difuminada a causa del blur. La buena noticia es que podemos crear el mismo efecto utilizando filtros SVG, con un resultado mucho mejor.

Utilizando filtros SVG

Esta "receta" viene explicada con mucho detalle en the gooey effect, un articulo escrito por Lucas Bebber.

El primer paso es aplicar, exactamente como antes, un desenfoque gaussiano al grafico de origen: SourceGraphic.

<filter id="goo">
       <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
       . . . . 
</filter>

El segundo paso es aumentar el contraste de la imagen resultante ( result="blur" ) pero solo del canal alpha, dejando sin cambiar los canales de color. Para esto utilizamos feColorMatrix:

<filter id="goo">
       <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
       <feColorMatrix in="blur" mode="matrix" 
                         values="1 0 0  0   0  
                                 0 1 0  0   0  
                                 0 0 1  0   0  
                                 0 0 0 40 -10" result="goo"/>
      . . . .
</filter>

Lea más acerca del filtro primitivo feColorMatrix

Finalmente utilizamos feBlend para aplicar el filtro resultante ( result="goo" ) al gráfico de origen ( SourceGraphic ).

  <filter id="goo">
          <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
          <feColorMatrix in="blur" mode="matrix" 
                         values="1 0 0  0   0  
                                 0 1 0  0   0  
                                 0 0 1  0   0  
                                 0 0 0 40 -10" result="goo"/>
          <feBlend  in="SourceGraphic" in2="goo" />
        </filter> 

Este es el filtro que vamos a utilizar en el CSS:

.contenedor {
      . . . . . . . 
      filter:url(#goo);
}

<svg  width="1" height="1">
	<defs>
		<filter id="goo">
        	<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
        	<feColorMatrix in="blur" mode="matrix"
                          values="1 0 0  0   0
                                  0 1 0  0   0
                                  0 0 1  0   0
                                  0 0 0 40  -10" result="goo"/>
        	<feBlend in="SourceGraphic" in2="goo" />
            </filter>
       </defs>
</svg>
<div class="contenedor">
<div class="pegajoso">A</div>
<div class="pegajoso">B</div> 
</div>

.contenedor {
  display: block;
  margin:0 auto;
  width: 300px;
  height: 260px;
  position: relative;
  filter:url(#goo);
}
.contenedor div {
  position: absolute;
  left: 60px;
  top: 90px;
  height: 80px;
  width: 80px;
  border-radius:50%;
  background-color: black;
  color:white;
  text-align:center;
  line-height:80px;
}
.contenedor div:nth-child(2){
  left: 140px;
}

Vea este ejemplo en codepen:

See the Pen GOO #2 SVG by Gabi (@enxaneta) on CodePen.

Vea también este menú animado que utiliza este tipo de filtros SVG. Haz clic en el ícono verde.

See the Pen gooey menu* by Gabi (@enxaneta) on CodePen.