Tres formas de crear blobs con CSS y SVG | Programar Plus

Los blobs son formas suaves, aleatorias y gelatinosas que tienen una cualidad caprichosa y son simplemente divertidas. Se pueden utilizar como elementos de ilustración y efectos de fondo en la web.

Entonces, ¿cómo se hacen? Simplemente abra una aplicación de ilustración y hágalo, ¿verdad? Claro, eso es genial. Pero estamos en una publicación aquí sobre CSS-Tricks, y sería mucho más divertido ver las posibilidades que tenemos para hacer esto con CSS y SVG, ¡dos de nuestros ingredientes favoritos!

De hecho, tenemos algunas formas de abordar las manchas. Echémosles un vistazo.

Dibujar círculos en SVG

Comencemos fácil. Podemos dibujar SVG en algo como Illustrator, Sketch, Figma o lo que sea, pero en su lugar dibujaremos en código SVG.

SVG hace que sea bastante trivial dibujar un círculo, gracias al nombre apropiado <circle> elemento:

<circle cx="100" cy="100" r="40" fill="red" />

Esos atributos funky? Tienen sentido una vez que los desglosas:

  • cx define la coordenada x del centro del círculo.
  • cy define la coordenada y.
  • r es el radio.
  • fill se utiliza para rellenar la forma con color.

Ese fragmento crea un círculo con un radio de 40 px con su centro en 100 px en el eje x y 100 px en el eje y. Las coordenadas comienzan en la esquina superior izquierda del contenedor principal.

Vamos a crear múltiples círculos superpuestos como este:

<svg height="300" width="300">
  <circle cx="80" cy="80" r="40" fill="red" />
  <circle cx="120" cy="80" r="40" fill="red" />
  <circle cx="150" cy="80" r="40" fill="red" />
  <circle cx="150" cy="120" r="40" fill="red" />
  <circle cx="100" cy="100" r="40" fill="red" />
</svg> 

<svg> actúa como el tablero de arte donde se dibujan todas las diferentes formas y figuras. Entonces, es height y width indica el tamaño en el que se debe encerrar todo el dibujo. Si alguna parte de la figura está fuera de los límites del tamaño del SVG, esa parte se truncará.

Pero las manchas no siempre son tan perfectas… redondas. Podemos mezclar las cosas usando <ellipse> en vez de <circle>:

<ellipse cx="200" cy="80" rx="100" ry="50" fill="red" />

Esto es casi idéntico al círculo, excepto por el cambio en el nombre de la etiqueta y dos valores de radio para definir la horizontal (rx) y verticales (ry) radios por separado. Lo curioso es que aún podemos obtener un círculo perfecto si queremos si los valores de los radios son los mismos. Entonces, en cierto sentido, <ellipse> es un poco más versátil.

Y, si todo lo que necesita es un círculo, probablemente podríamos apoyarnos en CSS sin SVG. Cualquier elemento de caja puede convertirse en un círculo o una elipse con border-radius.

.circle {
  border-radius: 50%;
  height: 50px;
  width: 50px;
}

…pero más sobre eso más adelante.

Estilo libre con trazados SVG

Gracias a los SVG <path> etiqueta, podemos crear cualquier tipo de forma. Es como dibujar con un lápiz o un bolígrafo. Empiezas desde un punto y dibujas líneas, curvas, formas y cierras el ciclo.

Hay muchos parámetros de datos en la ruta para diferentes tareas como:

  • M – Ir al grano
  • L – Línea de dibujo
  • C – Dibujar una curva
  • Q – Curva de Bézier
  • Z – Cerrando el camino

Chris tiene una guía súper completa que explica estos parámetros con gran detalle.

Solo necesitamos la curva (C) parámetro para el dibujo actual. Pero también moveremos el punto de partida y cerraremos el camino, así que alcanzaremos el M y Z parámetros también.

Una mancha verde con cuatro bordes que varían en tamaño y forma.Esta es una forma de blobby aleatoria que armé usando SVG <path> elemento.

¿Listo para analizar esto? Las coordenadas juegan un papel importante en <path> entonces, lo que estamos a punto de ver se verá como datos de Google Maps vomitados dentro de nuestro código. Pero tiene mucho más sentido cuando sabemos lo que están haciendo.

Toma esto…

<svg xmlns="http://www.w3.org/2000/svg">
  <path
    fill="#24A148"
    d=""
  />
</svg>

Aquí el d El atributo almacena los datos de la ruta. Contiene información que contiene dónde comienza el dibujo, en qué dirección se mueve, qué forma sigue y dónde termina. Por ejemplo:

<path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>

Muestra que nuestro camino parte de coordenadas 10 10, indicado por el M que les precede. Luego, establece una curva Cubic Bézier (C) con dos puntos de control. Las curvas de Bézier son como manijas en ambos extremos de un camino que controlan las curvas entre ellas. Tenemos dos “asas” Bézier: una para la posición inicial (20 20) de la curva y otro para la posición final (40 20).

Muestre hasta los puntos finales para una línea de ruta negra con líneas rojas claras que se extienden desde cada punto final que indican la cantidad de curva en cada punto.

Usemos este conocimiento para diseñar nuestro blob. La mancha que dibujé es en realidad un poco compleja, con varias curvas y puntos de control. No ayuda que muchas de las coordenadas no sean enteros completos. Pero, aun así, ahora que sabemos lo que <path> ‘s d hace el parámetro y los atributos que usa para dibujar puntos a lo largo de la ruta, no parece tan aterrador.

Pero bueno, lo entiendo. Eso es mucho código no solo para escribir a mano, sino también para hacerlo exactamente bien. No te culparía por usar algo como esta herramienta para generar el código por ti.

Efectos pegajosos con filtros CSS y SVG

La ruta SVG es compleja. ¿Correcto? ¿Qué pasa si te presento una forma de convertir muchas formas personalizadas (que puedes crear a través de divs) en gotas pegajosas? Aquí está la idea. Vamos a crear dos rectángulos que se intersecan. Son del mismo color, pero tienen un poco de transparencia para oscurecerse donde se cruzan.

Luego, aprovecharemos las funciones de desenfoque de SVG para difuminar los rectángulos, creando una mancha extra pegajosa con bordes más suaves. Los dos rectángulos que se cruzan se convertirán en esto:

Una mancha roja brillante con cuatro esquinas de diferentes formas y tamaños, como en forma de L invertida.

Primero comprendamos cómo funcionan los filtros en SVG. Se declaran usando <filter> en elementos HTML u otros elementos SVG, como circle.

circle {
  filter: url("#id_of_filter");
}

<filter> es básicamente un envoltorio para los efectos de filtro reales, que incluyen:

  • <feGaussianBlur>
  • <feImage>
  • <feMerge>
  • <feColorMatrix>
  • Muchos más… Obtén la lista completa aquí.

Nuestro blob está borroso y coloreado, por eso vamos a poner <feGaussianBlur> y <feColorMatrix> usar.

<feGaussianBlur> toma múltiples atributos, pero solo nos interesan dos de ellos: cuánto desenfoque queremos y dónde lo queremos. La desviación estándar (stdDeviation) y in las propiedades se alinean con esas necesidades, respectivamente.

in acepta uno de dos valores:

  • SourceGraphic – Desenfoca toda la forma
  • SourceAlpha – Difumina el valor alfa y se usa para crear efectos de sombra

Después de jugar un poco, aquí es donde aterricé en el <feGaussianBlur> efecto:

<feGaussianBlur in="SourceGraphic" stdDeviation="30" />

Esto va directamente en el marcado HTML con una ID que llamamos en el elemento principal de nuestro blob:

<!-- The SVG filter -->
<svg style="position: absolute; width: 0; height: 0;">
  <filter id="goo">
    <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
  </filter>
</svg>

<!-- The blob -->
<div class="hooks-main">
  <div></div>
  <div></div>
</div>

El filtro en realidad no se procesa, aunque está en el marcado. En su lugar, lo hacemos referencia como un filtro CSS en el elemento principal del blob:

/* Blob parent element */
.hooks-main {
  position: absolute;
  width: 100%;
  height: 100%;
  filter: url("#goo&amp");
  overflow: hidden;
}

Esto no está hecho todavía. El desenfoque se dispersa y la forma del elemento perdió su límite y color. Necesitamos un efecto abultado con desenfoque en los límites y un color sólido para llenar la forma. Aquí es donde nuestro próximo filtro SVG, <feColorMatrix>, entra en juego.

Hay dos <feColorMatrix> atributos que queremos:

  • in – Indica dónde se aplica el efecto, al igual que <feGaussianBlur>.
  • values – Una matriz de cuatro filas y cinco columnas.

El values El atributo tiene un poco más de matiz. Contiene una matriz que se multiplica con el color y los valores alfa de cada píxel y genera un nuevo valor de color para ese píxel. Matemáticamente hablando:

new pixel color value = ( values matrix ) × ( current pixel color value )

Vamos a ponernos un poco nerd de números aquí. En esa ecuación, values matrix es igual a:

[F-red1 F-green1 F-blue1 F-alpha1 F-constant1
 F-red2 F-green2 F-blue2 F-alpha2 F-constant2
 F-red3 F-green3 F-blue3 F-alpha3 F-constant3
 F-red4 F-green4 F-blue4 F-alpha4 F-constant4]

Aquí, F-red significa una fracción de rojo en píxeles, con un valor que va de 0 a 1. F-constant es un valor constante para sumar (o restar) del valor del color.

Desglosando esto aún más… Tenemos un píxel de color con un valor RGBA de rgba(214, 232, 250, 1). Para convertirlo en un nuevo color, lo multiplicaremos con nuestro values matriz.

Matriz de valores Píxel de color (RGBA) Nuevo color (RGBA)
[1 0 0 0 0
 0 1 0 0 0
 0 0 1 0 0
 0 0 0 1 0
 0 0 0 0 1]
× [214
 232
 250
 1
 1]
= [ 214x1 + 232x0 + 250x0 + 1x0 + 1x1
      214x0 + 232x1 + 250x0 + 1x0 + 1x1
      214x0 + 232x0 + 250x1 + 1x0 + 1x1
      214x0 + 232x0 + 250x0 + 1x1 + 1x1
      214x0 + 232x0 + 250x0 + 1x0 + 1x1 ]
= [214
  232
  250
 1
  1]

El valor de píxel no cambió porque lo multiplicamos por la matriz de identidad, pero si cambia los valores de la matriz, entonces su valor de píxel también cambiará. Aprender más acerca de values matriz de la documentación de MDN.

En nuestro caso, estos valores parecen funcionar bastante bien:

<filter id="goo">
  <feGaussianBlur in="SourceGraphic" stdDeviation="30" />
  <feColorMatrix
    in="blur"
    values="1 0 0 0 0 
            0 1 0 0 0 
            0 0 1 0 0 
            0 0 0 30 -7"
  />
</filter>

Agregué algunos estilos más en el blob para estirarlo desde la esquina.

Intente usar estos valores de filtro en otras formas y déjeme saber cómo funcionan para usted en los comentarios.

Usando CSS border-radius

Nos burlamos de esto antes, pero ahora vayamos al CSS border-radius propiedad. También puede crear una forma de gota, gracias a su capacidad para suavizar las esquinas de un elemento. Esto es posible porque cada radio de esquina se divide en dos radios, uno para cada borde. Es por eso que podemos tener más formas además del círculo y la elipse.

Cada esquina tiene dos radios, uno para cada borde.  Por ejemplo, el cordón superior izquierdo de una caja tiene dos radios, uno para el borde izquierdo y otro para el borde superior.

Puede que estés acostumbrado a usar border-radius como abreviatura de las cuatro esquinas de un elemento:

.rounded {
  border-radius: 25%;
}

Esa es una buena manera de obtener uniformidad en todas las esquinas. Pero las manchas no son tan uniformes. Queremos que algunas esquinas sean más redondas que otras para que se vean pegajosas. Es por eso que buscamos las propiedades constitutivas de border-radius, me gusta:

.element {
  border-top-left-radius: 70% 60%;
  border-top-right-radius: 30% 40%;
  border-bottom-right-radius: 30% 60%;
  border-bottom-left-radius: 70% 40%;
}

¿Y ves cómo cada propiedad toma dos valores? Eso es uno para cada borde de la esquina, lo que nos da mucha flexibilidad para curvar un elemento en formas interesantes. Luego podemos colocar un color de fondo, rellenarlo con un degradado o incluso establecer un box-shadow en él para obtener un efecto prolijo.

(Visited 5 times, 1 visits today)