hand Inicio

SERVICIOS

Salir

nochedía

CSS y JavaScript para conseguir gradientes animados

1200 palabras
5 minutos
July 9, 2020

No podemos generar gradientes animados directamente

Pero sí podemos simularlos con css, o fabricarlos con JavaScript

Prólogo

Conseguir un gradiente animado no es trivial

Podría serlo, pero en css los gradientes no son colores sino imágenes (por eso no dices background-color: linear-gradient... sino que utilizas la forma background: line...)

Y cómo lo podemos hacer? O lo simulamos con css puro, o lo hacemos de verdad con JavaScript

Vamos allá

  1. Prólogo
  2. Gradientes por css
  3. Gradientes con JavaScript

Gradientes por css

Los gradientes estáticos por css son extraordinariamente potentes en el sentido de que es el propio navegador el que nos renderiza esas imágenes y por lo tanto el rendimiento de nuestra página no se verá afectado

Por cierto, tienes una pequeña herramienta aquí para generar gradientes aleatorios por si necesitas inspiración

Cómo los podemos animar?

Más fácil de lo que parece, simplemente dibujando un gradiente gigante y ... moverlo

[ El código utiliza @emotion así que en los codesandbox que toquen no te olvides de añadir las dependencias @emotion/styled y @emotion/core ]

Se trata de un panel 4 veces más grande que nuestro viewport y que al moverlo nos da la impresión de que estamos cambiando el gradiente

Brillante y tremendamente barato, pero cuando acostumbras la vista es verdad que terminas detectando que es un panel que va oscilando

Importa? Eso ya depende de lo que busques con tu página web y tu gradiente animado

Ojo, un detalle importante pero no relacionado con el gradiente

Si te fijas, ese gradiente ocupa todo el largo de la pantalla con height: 100vh;

Esto no funciona como debería en móviles por el impacto que tiene la barra de navegación que a veces aparece y a veces no

Para solucionarlo basta con añadir un custom hook que nos calcule el heigh de verdad y nos lo vuelve como variable css, y a partir de ahí listos

Básicamente ponemos como altura el equivalente a los 100vh de antes pero a partir de la variable --vh que hemos fijado con useReplace100vh

Esa variable se basa en innerHeight, y esto sí tiene en cuenta la potencial barra superior de un navegador en móviles

Esto nos sirve por si queremos que ese fondo ocupe toda la pantalla, lo comento y me olvido pero que lo sepas

A partir de aquí, se trata de

  • Definir un gradiente con background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab, #ff1ef8);

  • Definir su tamaño con background-size: 400% 400%;

  • Definir un loop eterno que mueva ese gradiente con background-position

Fácil, eficiente y efectivo

Las animaciones en css constan de 2 momentos

  1. Definimos como se anima

Con el nombre que queramos (aquí gradientBG), la duración, el tipo de movimiento y si queremos que haya un loop infinito pues con infinite

El tipo de movimiento se define con curvas bezier pero la mayoría de veces nos bastará y sobrará con las que están predefinidas, como ease

Éstas son las predefinidas

image

Y si quieres curvas más sofisticadas puedes utilizar las de easings.net)

  1. Definimos la animación

Con la palabra clave @keyframes y seguido del nombre que antes hemos puesto

Luego definimos los porcentajes de la animación que nos parezcan, fíjate que aquí el 0% y el 100% son iguales, esto nos permitirá hacer un loop infinito sin que se perciba el inicio y final de la animación

Y lo que hacemos es cambiar la posición del background, donde establecemos la x y la y

Aquí por lo tanto estaremos siempre moviéndonos en el eje de las x

Podemos sofisticarlo un poco más y añadir un sol que nos aparece lentamente con radial-gradient

Aquí le estamos definiendo un círculo que termine cuando toque su lado más cercano (con closest-side), y luego utilizamos los colores indicados

Puedes ver la diferencia entre closest-side y farthest-side en esta imagen

image

Pero lo suyo es que lo pruebes en el codesandbox

Primero defino un fondo inmovil con <BackgroundImg>, lo hago con background-image, y añado una imagen de fondo y un gradiente radial

Y luego, éstas dos imágenes las mezclo con mix-blend-mode: hard-light; y background-blend-mode: multiply;

Y después, defino mí gradiente animado con <Background> donde en lugar de un fondo dibujo una suerte de sol

En el codesandbox verás como el sol aparece y desaparece muy rápidamente, pone un tiempo mucho más largo y ya lo tendrás

background-blend-mode se utiliza para mezclar background-image que esten en una misma instrucción

Si se quiere mezclar <div> distintos se utiliza mix-blend-mode

Y si lo que quieres es volver a la animación inicial, tan sencillo como cambiar los componentes

Gradientes con JavaScript

Para generar gradientes reales y no mover un panel gigante (que si tienes la vista acostumbrada los detectas, pero quién la tiene?) necesitamos JavaScript

Lo que haremos será modificar los colores

Cómo funcionan los colores en JavaScript

Si has escogido tus colores con el Chrome Developer Tools habrás descubierto que un mismo color se puede expresar de distintas maneras

El primero de todo es el hex, el que a mi más me gusta por ser más conciso y que representa lo mismo que el rgb pero en formato hexadecimal

Utilizando la función rgb() es por lo tanto lo mismo, y se trata de determinar el Red Green y Blue que especifica eso mismo, el rojo, verde y azul

Y el último es el hsl() por Hue, Saturation, Lightness, conceptos que si has ajustado tus fotos con algún programa especializado (yo soy de darktable) sabrás qué significan

  • El Hue nos determina el color, un valor de 0 a 360 que representa una rueda de colores
  • El Saturation nos determina lo intenso del color, una saturación de 0 es convertir el color en gris
  • Y el brillo, más del 50% implica añadir blanco (es decir, del 50 a 100 añadimos blanco, y menos del 50% añadimos negro)

*Podemos utilizar las funciones rgba() y hsla() y añadir un cuarto parámetro que implicará la opacidad

Entonces, si queremos un gradiente que pase por toda la tonalidad de colores lo más sencillo es utilizar la notación hsl() y cambiar solamente el Hue

Lo primero que haremos será definir el gradiente y pasárselo al componente <Background>

La función change_color nos cambia el color, en concreto el color del inicio y el primer número del color expresado en hsl

Cuando ejecutamos esa función?

Desde siempre, empezamos con el useState donde lo inicializamos, y a partir de aquí tenemos el useEffect que se nos ejecuta cada vez que color vuelva a cambiar

Esto lo hacemos hasta que color alcance los 180

Y utilizando window.requestAnimationFrame nos aseguramos que ese cambio no va demasiado rápido sino que se espera a que el navegador haya terminado con sus renderizados

Cómo podríamos mejorarlo?

Cambiando todos los valores del hsl, y a distintas velocidades, donde por velocidad se entiende la magnitud del cambio (cambiar de 1 en 1 o de 10 en 10)

Y además, en lugar de partir siempre desde el mismo gradiente, vamos a empezar desde un punto aleatorio

  1. Definimos un estado inicial random
  2. Lo cambiamos a distintas velocidades
  3. Ajustamos para que los valores siempre estén entre 0 y 255

El problema es que cambiando todos los valores de hsl al final el efecto es algo repetitivo, por lo que una opción mejor es fijar las dos últimas variables y cambiar sólo la primera (que es el color propiamente dicho)

El resultado final es un gradiente que no es continuo sino que cuando termina empieza de nuevo dando un efecto curioso

Si quisiésemos un efecto continuo posiblemente nos interesase cambiar de hsl a rgb y no reiniciar ningún valor sino que cuando éste llegase a 255 simplemente invertir el cambio para que volviese a 0 y así mantener un cambio suave y contínuo

Y si queremos implementarlo vía canvas, siempre podemos utilizar o explorar la fantástica librería granim.js

🙋‍♂️

Qué tal el curso?
👌 Bien 🙌🙌
👍 Bien, pero algunas cosas podrían explicarse mejor 😬
🤷‍♂️ Da por sentadas demasiadas cosas 😒
🤷‍♂️ A ver, hay poca chicha 😬
🤷‍♂️ Los ejemplos no son muy claros 🙇‍♂️
🤷‍♂️ No se entiende, está mal escrito 👎
✍️ Hay errores, revísalo en cuanto puedas 🙏

Quizá te interese

Privacidad
by kuworking.com
[ 2020 >> kuworking ]