Lecciones aprendidas de sesenta días de reanimación de zombis con CSS codificado a mano

Índice
  1. Lección 1: Ochenta días es mucho tiempo.
  2. Lección 2: Las animaciones interactivas son difíciles y aún más difíciles de hacer responsivas.
  3. Lección 3: Si desea una animación responsiva, coloque todo en (una de las) unidades de ventana gráfica.
  4. Lección 4: Los SVG escalan terriblemente en tiempo de ejecución.
  5. Lección 5: El eje no es una verdad universal.
  6. Lección 6. Separe animaciones complejas en elementos concéntricos para realizar ajustes más fáciles.
  7. Lección 7: Las transformaciones SVG y CSS son iguales.
  8. Lesson 8: Keep your sanity by using transform-origin when transforming part of an SVG
  9. Lesson 9: Sprite animations can be responsive
  10. Lesson 10: Invite people into the project.

Precaución: Terrible sentido del humor por delante. Hablaremos de cosas prácticas, pero casi todos los ejemplos involucran zombis y chistes tontos. Usted ha sido advertido.

Estaré vinculando bolígrafos individuales mientras analizo las lecciones que aprendí, pero si desea tener una idea de todo el proyecto, consulte 60 días de animación en Undead Institute . Comencé este proyecto para finalizar el 1 de agosto de 2020, coincidiendo con la publicación de un libro que escribí sobre animación CSS, humor y zombies, porque, obviamente, los zombies destruirán el mundo si no blandes tus habilidades web y te detienes. el Apocalipsis. ¡Nada causa más daño a la horda que un elemento HTML en movimiento!

Tuve algunas reglas para mí durante todo el proyecto.

  1. Codificaría manualmente todo CSS. (Soy masoquista).
  2. El usuario iniciaría toda la animación. (Odio encontrarme con una animación que ya está en la mitad).
  3. Usaría JavaScript lo menos posible y nunca para animación. (Solo terminé usando JavaScript una vez, y fue para iniciar el audio con la animación final. No tengo nada en contra de JavaScript, simplemente no es lo que quería hacer aquí).

Lección 1: Ochenta días es mucho tiempo.

¿No dice el título “sesenta” días? Sí, pero mi objetivo original era hacer ochenta días y a medida que se acercaba el primer día con menos de veinte animaciones preparadas y un promedio de tres días para cada producción, me asusté y cambié a sesenta días. Eso me dio veinte días más hasta la fecha de inicio y veinte piezas menos por hacer.

Lección 1A: Sesenta días es todavía mucho tiempo.

Es mucha animación que se puede hacer con una cantidad limitada de tiempo, ideas y habilidades artísticas aún más limitadas. Y aunque pensé en reducirlo a treinta días, me alegro de no haberlo hecho. Sesenta días me estiraron y me obligaron a profundizar en cómo funciona la animación CSS y, por extensión, el propio CSS. También estoy muy orgulloso de muchas de las piezas posteriores que hice a medida que mis habilidades aumentaron y tuve que ser más innovador y pensar más en cómo hacer las cosas interesantes. Una vez que haya utilizado todas las opciones sencillas, comenzará el trabajo real y los mejores resultados. (Y sí, terminaron siendo sesenta y dos días porque comencé el 1 de junio y quería hacer una animación final el 1 de agosto. Comenzar el 3 de junio me pareció asqueroso y equivocado).

Entonces, la verdadera Lección 1: estírate.

Lección 2: Las animaciones interactivas son difíciles y aún más difíciles de hacer responsivas.

Si quieres que algo vuele por la pantalla y se conecte con otro elemento o parezca iniciar el movimiento de otro elemento, debes usar todas las unidades estándar, inflexibles o todas las unidades flexibles.

Tres variables determinan cuándo y dónde estará un elemento animado durante cualquier animación: duración, velocidad y distancia. La duración de la animación se establece en la propiedad de animación y no se puede cambiar en relación con el tamaño de la pantalla. La función de sincronización de la animación determina la velocidad; El tamaño de la pantalla tampoco puede cambiar eso. Por lo tanto, si la distancia varía con el tamaño de la pantalla, la sincronización estará fuera de lugar en todas partes excepto en un ancho y alto de pantalla específicos.

¡Mira el tanque! . Ejecute la animación en tamaños de pantalla anchos y estrechos. Si bien acerqué el tiempo, si comparas los dos, verás que el tanque está en un lugar diferente en relación con los zombies cuando caen los últimos zombies.

Para evitar estos problemas de sincronización, puede utilizar unidades fijas y un número grande, como 2000 o 5000 píxeles o más, de modo que la animación cubra el ancho (o alto) de la pantalla para todos los monitores excepto los más grandes.

Lección 3: Si desea una animación responsiva, coloque todo en (una de las) unidades de ventana gráfica.

Ir a medias en las proporciones de las unidades (por ejemplo, establecer el ancho y el alto en píxeles, pero la ubicación y el movimiento con unidades de ventana gráfica) conducirá a resultados impredecibles. No utilices vw y vh al mismo tiempo, sino uno u otro; cualquiera que sea la orientación dominante. Mezclar unidades vh y vw hará que tu animación se vuelva “torpez”, que creo que es el término técnico.

Tomemos como ejemplo Superbly Zomborrific . Mezcla unidades de píxeles, vw y vh. La premisa es que el Super Zombie vuela hacia arriba mientras la “cámara” lo sigue. Super Zombie se estrella contra una repisa y cae mientras la cámara continúa, pero no lo entenderías si tu pantalla fuera lo suficientemente alta.

Eso también significa que si necesitas que algo entre desde arriba, como hice en Nobody Here But Us Humans , debes establecer la altura del vw lo suficientemente alta como para asegurar que el zombi ninja no sea visible en la mayoría de las relaciones de aspecto.

Lección 3A: Utilice unidades de píxeles para movimientos dentro de un elemento SVG.

Dicho todo esto, la transformación de elementos dentro de un elemento SVG no debe utilizar unidades de ventana gráfica. Las etiquetas SVG son su propio universo proporcional. El “píxel” SVG permanecerá proporcional dentro del elemento SVG con respecto a todos los demás elementos secundarios de SVG, mientras que las unidades de ventana gráfica no. Así que transforme con unidades de píxeles dentro de un elemento SVG, pero use unidades de ventana gráfica en cualquier otro lugar.

Lección 4: Los SVG escalan terriblemente en tiempo de ejecución.

Para animaciones, como Ups… , hice que la imagen SVG del zombi se escalara hasta cinco veces su tamaño, pero eso hace que los bordes sean borrosos. [Agita el puño ante los gráficos vectoriales “escalables”.]

/* Original code resulting in fuzzy edges */.zombie {  transform: scale(1);  width: 15vw;}.toggle-checkbox:checked ~ .zombie {  animation: 5s ease-in-out 0s reverseshrinkydink forwards;}@keyframes reverseshrinkydink {  0% {    transform: scale(1);  }  100% {    transform: scale(5);  }}

Aprendí a establecer sus dimensiones en las dimensiones finales que estarían vigentes al final de la animación, luego usé una transformación de escala para reducirlas al tamaño para el inicio de la animación.

/* Revised code */.zombie {  transform: scale(0.2);  width: 75vw;}.toggle-checkbox:checked ~ .zombie {  animation: 5s ease-in-out 0s reverseshrinkydink forwards;}@keyframes reverseshrinkydink {  0% {    transform: scale(0.2);  }  100% {    transform: scale(1);  }}

En resumen, el código revisado pasa de una versión reducida de la imagen a todo el ancho y alto. El navegador siempre representa en 1, lo que hace que los bordes sean nítidos y limpios en una escala de 1. Entonces, en lugar de escalar de 1 a 5, escalé de 0,2 a 1.

Lección 5: El eje no es una verdad universal.

Los ejes de un elemento permanecen sincronizados con el elemento, no con la página. Una rotación de 90 grados antes de translateXcambiará la dirección translateXde horizontal a vertical. En Nadie aquí excepto nosotros los humanos… 2 , volteé a los zombies usando una rotación de 180 grados. Pero los valores positivos de Y mueven a los ninjas hacia la cima, y ​​los negativos los mueven hacia la parte inferior (lo opuesto a lo normal). Tenga cuidado con cómo una rotación puede afectar las transformaciones más adelante.

Lección 6. Separe animaciones complejas en elementos concéntricos para realizar ajustes más fáciles.

Al crear una animación compleja que se mueve en múltiples direcciones, agregar divs envolventes, o más bien elementos principales, y animar cada uno individualmente reducirá las transformaciones conflictivas y evitará que se convierta en un desastre.

Por ejemplo, en Space Cadet , tuve tres transformaciones diferentes. El primero es el movimiento del zombie-o-nauta hacia arriba y hacia abajo. El segundo es un movimiento a través de la pantalla. El tercero es una rotación. En lugar de intentar hacer todo en una sola transformación, agregué dos elementos envolventes e hice una animación en cada elemento (también guardé mi cabello… al menos una parte). Esto ayudó a evitar los problemas de eje discutidos en la última lección porque realizó la rotación en el elemento más interno, dejando los ejes de sus padres y abuelos en su lugar.

Lección 7: Las transformaciones SVG y CSS son iguales.

Algunas rutas y grupos y otros elementos SVG ya tendrán transformaciones definidas. Podría deberse a un algoritmo de optimización, o tal vez sea simplemente la forma en que el software de ilustración genera el código. Si una ruta, grupo o cualquier elemento en un SVG ya tiene una transformación SVG, eliminar esa transformación restablecerá el elemento, a menudo a una ubicación o tamaño extraño en comparación con el resto del dibujo.

Dado que las transformaciones SVG y CSS son iguales, cualquier transformación CSS que realice reemplaza la transformación SVG, lo que significa que su transformación CSS comenzará desde esa ubicación o tamaño extraño en lugar de la ubicación o tamaño establecido en el SVG.

Puede copiar la transformación del elemento SVG a su CSS y establecerla como posición inicial en CSS (actualizándola primero a la sintaxis de CSS, por supuesto). Luego puedes modificarlo en tu animación CSS.

For instance, in Uhhh, Yeah…, my tribute to Office Space, Undead Lumbergh’s right upper arm (the #arm2 element) had a transform on it in the original SVG code.

path fill="#91c1a3" fill-rule="nonzero" d="M0 171h9v9H0z" transform="translate(0 -343) scale(4 3.55)"/

Moving that transform to CSS like this:

path fill="#91c1a3" fill-rule="nonzero" d="M0 171h9v9H0z"/
#arm2 {  transform: translate(0, -343px) scale(4, 3.55);}

…I could then create an animation that doesn’t accidentally reset the location and scale:

.toggle-checkbox:checked ~ .z #arm2 {   animation: 6s ease-in-out 0.15s arm2move forwards;}@keyframes arm2move {  0%, 100% {    transform: translate(0, -343px) scale(4, 3.55);  }  40%, 60% {    transform: translate(0, -403px) scale(4, 3.55);  }  50% {    transform: translate(0, -408px) scale(4, 3.55);  }} 

This process is harder when the tool generating the SVG code attempts to “simplify” the transform into a matrix. While you can recreate the matrix transform by copying it into the CSS, it is a difficult task to do. You’re a better developer than me — which might be true anyway — if you can take a matrix transform and manipulate it to scale, rotate, or translate in the exact way you want.

Alternatively, you can recreate the matrix transform using translation, rotation, and scaling, but if the path is complex, the likelihood that you can recreate it in a timely manner without finding yourself in a straight jacket is low.

The last and probably easiest option is to wrap the element in a group (g) tag. Add a class or ID to it for easy CSS access and transform the group itself, thus separating out the transforms as discussed in the last lesson.

Lesson 8: Keep your sanity by using transform-origin when transforming part of an SVG

The CSS transform-origin property moves the point around which the transform happens. If you’re trying to rotate an arm — like I did in Clubbin’ It — your animation will look more natural if you rotate the arm from the center of the shoulder, but that path’s natural transform origin is in the upper-left. Use transform-origin to fix this for smoother, more natural feel… you know that really natural pixel art look…

Transforming the origin can also be useful when scaling, like I did in Mustachioed Oops, or when rotating mouth movements, such as the dinosaur’s jaw in Super Tasty. If you don’t change the origin, the transforms will use an origin point at the upper left corner of the SVG element.

Lesson 9: Sprite animations can be responsive

I ended up doing a lot of sprite animations for this project (i.e., where you use multiple, incremental frames and switch between them fast enough that the characters seem to move). I created the images in one wide file, added them as a background image to an element the size of a single frame, used background-size to set the background image to the width of the image, and hid the overflow. Then I used background-position and the animation timing function, step(), to walk through the images; for example: Post-Apocalyptic Celebrations.

Before the project, I always used inflexible images. I’d scale things down a little so that there would be at least a little responsive give, but I didn’t think you could make it a fully flexible width. However, if you use SVG as the background image you can then use viewport units to scale the element along with the changing screen size. The only problem is the background position. However, if you use viewport units for that, it will stay in sync. Check that out in Finally, Alone with my Sandwich…

Lesson 9A: Use viewport units to set the background size of an image when creating responsive sprite animation

As I’ve learned throughout this project, using a single type of unit is almost always the way to go. Initially, I’d set my sprite’s background size using percentages. The math was easy (100% * (number of steps + 1)) and it worked fine in most cases. In longer animations, however, the exact frame tracking could be off and parts of the wrong sprite frame might display. The problem grows as more frames are added to the sprite.

I’m not sure the exact reason this causes an issue, but I believe it’s because of rounding errors that compound over the length of the sprite sheet (the amount of the shift increases with the number of frames).

For my final animation, It Ain’t Over Till the Zombie Sings, I had a dinosaur open his mouth to reveal a zombie Viking singing (while lasers fired in the background plus there was dancing, accordions playing and zombies fired from cannons, of course). Yeah, I know how to throw a party… a nerd party.

The dinosaur and viking was one of the longest sprite animations I did for the project. But when I used percentages to set the background size, the tracking would be off at certain sizes in Safari. By the end of the animation, part of the dinosaur’s nose from a different frame would appear to the right and a similar part of the nose would be missing on the left.

This was super frustrating to diagnose because it seemed to work fine in Chrome and I’d think I fixed it in Safari only to look at a slightly different screen size and see the frame off again. However, if I used consistent units — i.e. vw for background-size, frame width, and background-position — everything worked fine. Again, it comes down to working with consistent units!

Lesson 10: Invite people into the project.

While I learned tons of things during this process, I beat my head against the wall for most of it (often until the wall broke or my head did… I can’t tell). While that’s one way to do it, even if you’re hard-headed, you’ll still end up with a headache. Invite others into your project, be it for advice, to point out an obvious blind spot you missed, provide feedback, help with the project, or simply to encourage you to keep going when the scope is stupidly and arbitrarily large.

So let me put this lesson into practice. What are your thoughts? How will you stop the zombie hordes with CSS animation? What stupidly and arbitrarily large project will you take on to stretch yourself?

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion