Recientemente he codificado en vivo una explosión de partículas de arco iris aleatoria en CSS puro. Hay una fuente en el medio de la pantalla, y las partículas del arco iris se disparan con diferentes velocidades en diferentes momentos y luego se desvanecen. Puede parecer el tipo de cosa que requiere mucho trabajo y código, pero es algo que hice bastante rápido y con solo 30 líneas de SCSS.
GIF de la animación de explosión de partículas.
Este artículo trata sobre mostrar un truco particularmente interesante: hay solo un conjunto de fotogramas clave utilizado para mover todas esas partículas en la pantalla! Hay un segundo que se encarga de desvanecerlos. Pero, a pesar de que terminan en posiciones completamente diferentes en la pantalla, solo un conjunto de fotogramas clave está a cargo de eso.
¡Veamos cómo funciona todo!
Estructura
No pasa mucho aquí. Simplemente dejamos caer 400
partículas en el body
elemento. Usé Haml porque creo que proporciona la forma más sencilla de bucle que ni siquiera implica una variable de bucle que no voy a necesitar de todos modos. Tenga en cuenta que todo depende de las preferencias personales. Tiendo a ir con el preprocesador que me da el resultado que quiero con la menor cantidad de código porque cuanto menos necesito escribir, mejor. En este caso particular, resulta ser Haml. Pero, al final del día, cualquier preprocesador que le permita generar todos los .particle
Los elementos en un bucle funcionan bien.
- 400.times do
.particle
Estilos básicos
Lo primero que hacemos es dimensionar nuestras partículas y posicionarlas absolutamente. Elegí hacerlos 4x4
cuadrados porque iba por un look pixelado.
$d: 4px;
.particle {
position: absolute;
width: $d; height: $d;
}
Posicionamiento aleatorio en la pantalla
Pasamos por estos 400
partículas (tenga en cuenta que el número en el @for
bucle en el SCSS debe ser el mismo número que el que hemos usado en el bucle Haml) y los traducimos al azar x,y
puntos en la pantalla, donde x
está entre 1vw
y 100vw
y y
está entre 1vh
y 100vh
. random(100)
nos da enteros aleatorios entre 1
y 100
, ambos inclusive.
Al mismo tiempo, también les damos a estas partículas diferentes fondos aleatorios para que podamos verlas. Elegimos el hsl()
formato porque es el más conveniente aquí. random(360)
cubre toda la rueda de tonos dándonos valores aleatorios entre 1
y 360
.
Escala de matices de 0 a 360.
Luego maximizamos la saturación (100%
) y listo para una ligereza por encima 50%
(65%
en este caso).
.particle {
/* same styles as before */
@for $i from 0 to 400 {
&:nth-child(#{$i + 1}) {
transform: translate(random(100)*1vw, random(100)*1vh);
background: hsl(random(360), 100%, 65%);
}
}
}
Ahora podemos ver nuestras partículas distribuidas por toda la pantalla:
Vea el lápiz de thebabydino (@thebabydino) en CodePen.
Activan barras de desplazamiento, así que configuramos overflow: hidden
en el elemento raíz. También le damos un tono oscuro background
para que podamos ver mejor nuestras partículas ligeras del arco iris:
html {
overflow: hidden;
background: #222;
}
De esta manera, obtenemos un bonito cielo nocturno:
Vea el lápiz de thebabydino (@thebabydino) en CodePen.
Animación
El siguiente paso es animar estas partículas, haciéndolas disparar desde el centro de la pantalla. Esto significa que nuestra animación comienza en el 50vw,50vh
punto:
@keyframes shoot {
0% { transform: translate(50vw, 50vh); }
}
No especificamos una final (100%
) fotograma clave. Si no se especifica, se genera automáticamente a partir de los estilos que hemos establecido en los elementos que animamos; en nuestro caso, estas son las traducciones aleatorias, diferentes para todas y cada una de las partículas.
Queremos que el movimiento de las partículas sea rápido al principio y luego más lento, lo que significa que necesitamos usar un tipo de función de sincronización. Podemos ir por el viejo llano ease-out
, o podemos usar uno más avanzado (voy a easings.net para esto). Luego damos nuestro animation
una duración ficticia de 3s
y haz que se repita infinitamente.
.particle {
/* same styles as before */
animation: shoot 3s ease-out infinite;
}
Obtenemos el siguiente resultado:
Vea el lápiz de thebabydino (@thebabydino) en CodePen.
Las partículas se disparan a diferentes posiciones en el avión, tal como queríamos. Pero todos se animan a la vez, que no es lo que queremos. Así que la primera solución es darle a cada uno de ellos una duración de animación aleatoria diferente entre 1s
y 3s
dentro del bucle:
.particle {
/* same styles as before */
@for $i from 0 to 400 {
$t: (1 + .01*random(200))*1s;
&:nth-child(#{$i + 1}) {
/* same styles as before */
animation-duration: $t;
}
}
}
Esto es mucho mejor:
Vea el lápiz de thebabydino (@thebabydino) en CodePen.
Luego le damos a cada partícula un retraso negativo aleatorio entre 0%
y 100%
de su animation-duration
($t
) en valor absoluto:
.particle {
/* same styles as before */
@for $i from 0 to 400 {
$t: (1 + .01*random(200))*1s;
&:nth-child(#{$i + 1}) {
/* same styles as before */
animation-delay: -.01*random(100)*$t;
}
}
}
Vea el lápiz de thebabydino (@thebabydino) en CodePen.
Finalmente, no queremos que las partículas simplemente desaparezcan, por lo que agregamos una segunda animación (con la misma duración y el mismo retraso) para desvanecerlas:
.particle {
/* same styles as before */
animation: shoot 0s ease-out infinite;
animation-name: shoot, fade;
}
@keyframes fade { to { opacity: 0; } }
¡Ahora tenemos el resultado final!
Vea el lápiz de thebabydino (@thebabydino) en CodePen.