search
HomeWeb Front-endCSS TutorialLessons Learned from Sixty Days of Re-Animating Zombies with Hand-Coded CSS

Ten lessons learned from 60 days of pure CSS zombie animation

Lessons Learned from Sixty Days of Re-Animating Zombies with Hand-Coded CSS

Warning: High-energy warning ahead, a large number of zombies and spoof content are coming! This article will share some practical tips, but the examples are almost all related to zombies and funny jokes. Please be mentally prepared.

I'll link to individual animation works in the discussion, but if you want to know the entire project, visit the Undead Institute to view the 60 Days Animation series. The project started on June 1, 2020 and ended on August 1, which coincides with the publication date of a book I wrote about CSS animation, humor and zombies – because it’s obvious that zombies will destroy the world without using your web skills to stop the end of the world. Nothing can hit zombies better than dynamic HTML elements!

I made some rules for myself throughout the project:

  1. All CSS code needs to be written manually. (I am just a masochist.)
  2. All animations are triggered by the user. (I hate animations that are halfway through.)
  3. Use JavaScript as little as possible and never use it for animation. (I only used JavaScript once in the final animation, that was to start the audio. I'm not against JavaScript, it's just that it's not needed here.)

Lesson 1: 80 days are too long.

Doesn’t the title say “60 days”? Yes, but my initial goal was 80 days, and when the first day arrived, I had less than 20 animations ready, and the average production time for each animation was 3 days, I was panicked and changed to 60 days. This gave me 20 more days of preparation time and reduced 20 animation works.

Lesson 1A: 60 days are still too long.

It is indeed a challenge to accomplish so much animation with limited time, creativity and more limited artistic skills. Although I had thought of shortening to 30 days, I'm glad I didn't do that. 60 days allowed me to break through myself and gain a deeper understanding of how CSS animations—and CSS itself—works. I’m also proud of many of the works I’ve completed later because my skills have improved, I have to be more innovative and think more deeply about how to make the work more interesting. Once you run out of all the simple options, the real work and the best results will begin. (Yes, it ends up being 62 days, because I started on June 1 and wanted to finish the final animation on August 1. It feels awkward from June 3.)

So, real lesson 1: Challenge yourself .

Lesson 2: Interactive animation is difficult to produce, and responsive design is even harder.

If you want an element to fly across the screen and connect with another element, or seem to initiate movement of another element, you have to use all standard, inflexible units or all flexible units.

Three variables determine the time and position of an animation element during any animation process: duration, speed, and distance. The duration of the animation is set in the animation property and cannot be changed according to the screen size. The animation time function determines the speed; the screen size cannot change this. Therefore, if the distance varies with screen size, there will be deviations in timing except for the specific screen width and height.

Check out Tank! Run animations on wide and narrow screens. Although I've scheduled it very close, if you compare, you'll find that when the last zombie falls, the tank's position relative to the zombie is different.

To avoid these time issues, you can use fixed units and a larger number, such as 2000 or 5000 pixels or more, so that the animation can cover the width (or height) of all displays except the maximum display.

Lesson 3: If you want responsive animations, put everything into (one of them) viewport units.

Taking a compromise solution for unit proportions (for example, setting width and height in pixels, but setting position and movement in viewport units) can lead to unpredictable results. Also, don't use vw and vh at the same time, but use one of them; which is the main direction. A mix of vh and vw units will make your animation "weird", which I believe is a professional term.

For example, take a look at Superbly Zomborrific. It uses a mix of pixels, vw and vh units. The premise is that the super zombie flies upwards and the "camera" follows. The super zombie hits a ledge and falls off while the camera continues to move, but if your screen is high enough you won't understand that.

This also means that if you need something to go from the top - like I did in Nobody Here But Us Humans - you have to set vw height high enough to make sure that the ninja zombies are not visible in most aspect ratios.

Lesson 3A: Use pixel units for movement inside an SVG element.

That is, converting elements within SVG elements should not use viewport units. SVG tags are their own proportional universe. The SVG "pixel" will maintain a ratio of all its other SVG element within the SVG element , while the viewport unit will not. Therefore, use pixel units within the SVG element for conversion, but use viewport units elsewhere.

Lesson 4: SVG scales poorly at runtime.

For animations, such as Oops…, I zoomed in the SVG image of the zombie to five times the original, but this blurred the edges. [Wave fists on "scalable" vector graphics. ]

 /* Original code that causes blurring of 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);
 }
}

I learned to set their size to the final size that will take effect at the end of the animation, and then use the zoom transformation to reduce them to the size at the beginning of the animation.

 /* Modified 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);
 }
}

In short, the modified code moves from a reduced version of the image to its full width and height. The browser always renders at 1, so that the edges are clear and sharp at a scale of 1. So instead of scaling from 1 to 5, I scaled from 0.2 to 1.

Lesson 5: Axis are not universal truths.

The axis of an element is kept in sync with itself, not the page. Performing a 90-degree rotation before translateX changes the direction of translateX from horizontal to vertical. In Nobody Here But Us Humans… 2, I flipped the zombies using 180 degree rotation. But a positive Y value will move the ninjas to the top and a negative value will move them to the bottom (as opposed to normal). Note how rotation affects subsequent transformations.

Lessons 6. Decompose complex animations into concentric elements for easy adjustment.

When creating complex animations that move in multiple directions, adding wrapping divs or parent elements and animate each element separately can reduce transformation conflicts and prevent you from crashing.

For example, in Space Cadet, I have three different transformations. The first is the up and down movement of astronauts and zombies. The second is horizontal movement. The third is rotation. Instead of trying to do everything in one transformation, I added two wrapping elements and animated them on each element (I also saved my hair...at least part of it). This helps avoid the axis issue discussed in the previous lesson, as I rotated on the innermost element, thus retaining the axis of its parent and grandparent elements.

Lesson 7: SVG and CSS transformations are the same.

Some paths, groups, and other SVG elements have already defined transformations on it. This may be caused by optimization algorithms, or it may be just the way the illustration software generates code. If a path, group, or any other element in an SVG already has an SVG transformation, deleting that transformation resets the element, usually with a singular change in position or size compared to the rest of the drawings.

Since SVG and CSS transforms are the same, any CSS transform you do replace the SVG transform, which means your CSS transform will start at that singular position or size, not the position or size set in the SVG.

You can copy the transform from the SVG element to the CSS and set it to the start position in the CSS (first update it to CSS syntax). You can then modify it in the CSS animation.

For example, in my Office Worker tribute work Uhhh, Yeah…, the Ultimate Renberg’s upper right arm (#arm2 element) has a transformation in the original SVG code.

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

Move the transformation into CSS as follows:

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

...I can then create an animation that does not accidentally reset the position 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 even more difficult when the tool that generates SVG code tries to "simplify" the transformation into a matrix. While you can recreate matrix transformations by copying them to CSS, scaling, rotating, or panning exactly the way you want is a daunting task.

Alternatively, you can use translation, rotation, and scaling to recreate the matrix transformation, but if the path is complex, the chances of you being able to recreate it in time without getting yourself in trouble are low.

The last and easiest option is to use a group ( ) Tag wrapping elements. Add a class or ID to it for easy access to CSS and transform the group itself, thus separating the transformations, as discussed in the previous lesson.

Lesson 8: Stay sane when transforming part of an SVG

CSS transform-origin property moves the point at which the transformation occurs. If you try to rotate your arms – like I did in Clubbin’ It – your animation will look more natural if you rotate your arms from the center of your shoulder, but the natural transformation origin of that path is in the upper left corner. Use transform-origin to fix this for a smoother, more natural feel…you know that very natural pixel art look…

When zooming, it's also useful to transform the origin, like I did in Mustachioed Oops, or when rotating the mouth movement, like the chin of a dinosaur in Super Tasty. If you do not change the origin, the transformation will use the origin in 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. you use multiple incremental frames and quickly switch between them to make the character look moving). I created images in a wide file, added them as background images to elements of a single frame size, set the background image to the width of the image using background-size , and hide the overflow. Then, I use background-position and animation time function step() to iterate through the image; for example: Post-Apocalyptic Celebrations.

Before the project, I've been using inflexible images. I'll scale down a little bit so that there will be at least some responsive effects, but I don't think you can make it a completely flexible width. However, if you use SVG as the background image, you can use viewport units to scale elements as the screen size changes. The only problem is the background location. However, if you use viewport units for this, it will remain synchronized. Check this out in Finally, Alone with my Sandwich….

Lesson 9A: Set the background size of the image using viewport units when creating responsive sprite animations

As I learned in this project, using a single type of unit is almost always feasible. Initially, I used percentages to set the background size of the sprite. The calculation is simple (100% * (step 1)) and works fine in most cases. However, in longer animations, precise frame tracking can go wrong and may display parts of the wrong sprite frame. The problem will get worse as more frames are added to the sprite.

I'm not sure exactly why this is causing the problem, but I think it's due to the rounding error accumulated over the sprite table length (the amount of displacement increases as the number of frames increases).

In my final animation It Ain't Over Till the Zombie Sings, I let a dinosaur open my mouth to reveal a zombie Viking singing (although there are laser firing in the background, and of course, dancing, accordion playing and zombies fired from cannons). Yes, I know how to host a party…a geek party.

Dinosaurs and Vikings are one of the longest elves animations made for the project. However, when I use percentages to set the background size, some sizes of tracking in Safari errors. At the end of the animation, a part of the dinosaur nose from different frames appears to appear on the right side, while a similar part of the nose is missing on the left side.

This is very difficult to diagnose because it seems to work fine in Chrome, and I think I fixed it in Safari and just look at a slightly different screen size and I see the frame deviation again. But if I use consistent units - i.e. vw for background-size , frame width and background-position - everything works fine. Again, this comes down to using consistent units!

Lesson 10: Invite people to participate in the project.

Although I learned a lot in the process, I spent most of my time hitting the wall (often until the wall is broken or my head is broken…I can’t tell the difference). Although this is a method, even if you are stubborn, you will end up having a headache. Invite others to participate in your project, whether it’s seeking advice, pointing out obvious blind spots you’ve missed, providing feedback, helping with the project, or encouraging you to keep going when you feel the scope is too large.

So let me put this lesson into practice. What are your thoughts? How will you block zombies with CSS animation? What projects will you undertake that are too large to challenge yourself?

The above is the detailed content of Lessons Learned from Sixty Days of Re-Animating Zombies with Hand-Coded CSS. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
A Little Reminder That Pseudo Elements are Children, Kinda.A Little Reminder That Pseudo Elements are Children, Kinda.Apr 19, 2025 am 11:39 AM

Here's a container with some child elements:

Menus with 'Dynamic Hit Areas'Menus with 'Dynamic Hit Areas'Apr 19, 2025 am 11:37 AM

Flyout menus! The second you need to implement a menu that uses a hover event to display more menu items, you're in tricky territory. For one, they should

Improving Video Accessibility with WebVTTImproving Video Accessibility with WebVTTApr 19, 2025 am 11:27 AM

"The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect."- Tim Berners-Lee

Weekly Platform News: CSS ::marker pseudo-element, pre-rendering web components, adding Webmention to your siteWeekly Platform News: CSS ::marker pseudo-element, pre-rendering web components, adding Webmention to your siteApr 19, 2025 am 11:25 AM

In this week's roundup: datepickers are giving keyboard users headaches, a new web component compiler that helps fight FOUC, we finally get our hands on styling list item markers, and four steps to getting webmentions on your site.

Making width and flexible items play nice togetherMaking width and flexible items play nice togetherApr 19, 2025 am 11:23 AM

The short answer: flex-shrink and flex-basis are probably what you’re lookin’ for.

Position Sticky and Table HeadersPosition Sticky and Table HeadersApr 19, 2025 am 11:21 AM

You can't position: sticky; a

Weekly Platform News: HTML Inspection in Search Console, Global Scope of Scripts, Babel env Adds defaults QueryWeekly Platform News: HTML Inspection in Search Console, Global Scope of Scripts, Babel env Adds defaults QueryApr 19, 2025 am 11:18 AM

In this week's look around the world of web platform news, Google Search Console makes it easier to view crawled markup, we learn that custom properties

IndieWeb and WebmentionsIndieWeb and WebmentionsApr 19, 2025 am 11:16 AM

The IndieWeb is a thing! They've got a conference coming up and everything. The New Yorker is even writing about it:

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.