Animar a diferentes estados finales usando un conjunto de fotogramas clave CSS | Programar Plus

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.

(Visited 6 times, 1 visits today)