JTech Communications Logo
JTech Communications

Using Adobe After Effects to Design and Prototype 3D CSS Animations: Part II

By Tyler Miller - Last Updated on 11/20/2013
Using Adobe After Effects to prototype 3D CSS animations and transforms, as well as 2D CSS animations and transforms can save your development team from spending hours of time tweaking timing and worrying about how the animation is supposed to look. Prototyping mockups in After Effects helps your creative team focus on the end result, while giving your development team a guide to the intended result, saving time and money.

Proof of Concept

Our development team created some limited code with a few objects and roughly placed them. Once the animation was complete, we tested out a few browsers. Immediately, we realized that all browsers — even the latest Safari and Chrome — balked in the presence of blurring that many objects. We’d expected this would happen, but had wanted to see what we could get away with. We found rather strict limitations on how many objects could be on screen at any given time — which meant going back into After Effects and modifying positions again. Not to mention we were only showing about 8-12 pieces in the CSS proof, and we knew there would be A LOT more objects in the final in order to make the world feel full and complete. This meant we needed to find another way to show the numerous other objects that we knew would have to be there, without generating their blur levels dynamically. To solve our blur problem, I proposed that we continue using the CSS Blur filter on the 18 objects that were to be traveled to and through. The other objects required to fill out the environment would have to be static images that were pre-blurred and optimized for web output in Photoshop. Even though their blur levels wouldn’t change, they were farther from the camera and the lack of dynamically changing blur wouldn’t be very noticeable. I went back into After Effects and rearranged my objects so that there were fewer than 6 objects in view at any given time, including along all points in the path — not just when you were paused on an object. I also started placing the “dummy” objects that would allow me to fill the world, providing visual engagement. The dummy objects’s only purpose was for visual appeal. These dummy objects were not to be traveled to, only to entertain the viewer as they were traveling, and increase the sense of movement throughout the world.


Finishing the World in After Effects

I ended up placing an additional 74 objects in order to make the world appealing no matter where you were in it. What resulted was the creation of object bands. My foreground contained the 18 active objects, with all of the faked objects behind. The critical viewpoint was was the depth of the world behind the objects you flew past and landed on. The middle ground contained pngs that had been pre-blurred and resized to be a bit smaller, then optimized for the best browser performance. (See Fig. 10, 11)



Fig. 10, 11 - This was the top down view after placing the 18 objects. To avoid seeing duplicates, the field inevitably became more of a band, left to right. The rest of the objects were placed, continuing the theme of bands. They were placed behind the active objects because their sole purpose was just to provide the viewer something more engaging to look at while traveling among the active objects. It also gave a much greater sense of movement and really enhanced the animation altogether.

My background “band” contained even smaller pngs, with stronger blur. The reason we shrunk the faked objects was to artificially increase the depth of field — allowing us to decrease the z-axis values in CSS and accelerate the background’s effective motion compared to our 18 active objects. The further out on the z-axis an object was placed, the harder it was to get it out of view to create the sensation of movement. Think of it in terms of driving down a road, where the telephone poles fly past you at great speed, while the mountains in the background tend to casually mosey along. We essentially made the “mountains” smaller so that they appeared to be the same relative size, but positioned them only a few hundred yards from the “telephone poles” so that they moved bit quicker. The net result was a world that contained more movement and provided an interesting and unique experience.

These were placed carefully so that they didn't cause any distracting placement or clipping issues when you moved through space or paused on an object. We didn’t mind if objects appeared behind the navigation menu or the footer, but we wanted to make sure there weren’t any scenarios that took away from the usability and aesthetic of the home page. (See Fig. 12, 13)



Fig. 12, 13 - The first screenshot illustrates the how the rest of the objects could pose a problem with regards to clipping/non ideal positioning/distracting situations. The second screenshot illustrates how positioning could cause clipping. Objects were rearranged until this didn’t happen anymore.


Building it in the Browser.

In the first iteration of code after our initial experiment, we used the position coordinates from my After Effects composition to create the matrix of objects in code. I had two sets of coordinates: one for the 18 dynamic objects, and one for the rest of the faked objects. I asked our development team if the After Effects coordinates I had were useful. It was great news when they told me we could use the same coordinates in code as I did in After Effects. Only then did I realize I had to extract the coordinates for 80+ objects. I found the process of gathering each property value manually quite cumbersome. I quickly gave in and asked Patrick, our VP of Technology, to develop a script that would capture the data we needed straight from After Effects. Because we planned to continue tweaking our objects’ coordinates, the script needed to export positions so they could be easily implemented into the website code. After Effects scripting turns out to be similar to Javascript — and Patrick whipped up a script that grabbed the X, Y, and Z coordinates for any layers I had highlighted in the layer palette.

This version exports the layer name, position coordinates, and scale:
var comp = app.project.activeItem;
var file = new File(Folder.desktop.absoluteURI + "/" + "positions.csv");
file.open("w");
for (var i = 0; i < comp.selectedLayers.length; i++) {
    var layer = comp.selectedLayers[i];
    var point = layer.transform.position.valueAtTime(layer.inPoint, false);
    var scale = layer.transform.scale.valueAtTime(layer.inPoint, false);
    var id = layer.name;
    file.writeln(id+","+Math.round(point[0])+", "+Math.round(point[1])+","+Math.round(point[2])+","+Math.round(scale[0]));
}
file.close();
alert("Positions.csv has been saved to your desktop”);

This version exports everything except the layer name:
var comp = app.project.activeItem;
var file = new File(Folder.desktop.absoluteURI + "/" + "positions.csv");
file.open("w");
for (var i = 0; i < comp.selectedLayers.length; i++) {
    var layer = comp.selectedLayers[i];
    var point = layer.transform.position.valueAtTime(layer.inPoint, false);
    var scale = layer.transform.scale.valueAtTime(layer.inPoint, false);
    file.writeln(Math.round(point[0])+", "+Math.round(point[1])+","+Math.round(point[2])+","+Math.round(scale[0]));
}
file.close();
alert("Positions.csv has been saved to your desktop");


The script worked like a dream, outputting the data in a CSV that was ready for him to parse and integrate into his code. Now he had all of the objects in the environment just as I had them in After Effects. Initially, we found that the field of view was drastically different. Fortunately, we were able to tweak the CSS Perspective property. In fact, we kept tweaking it until I had the idea of just trying the same value I had used for the “Zoom” and “Focus Distance” properties in After Effects. Turns out, CSS Perspective is equivalent to the Zoom property in After Effects. We were able to replicate the relative sizes and positioning of objects, which saved us a lot of time reproducing my careful placement of the objects based on my own perspective in After Effects.

Before we did any real animating, we had to implement a method that would populate our 18 active objects with our 18 most recent portfolio pieces, and choose 6 of them at random, for the path we had developed. Using PHP and Javascript, our code pulls records from a database and places the images in these objects. Even more cool, you could click on the object you were focused on and it would take you to the same portfolio piece’s case study on our portfolio page. This random populating of objects was session-based, so that the experience is consistent for the duration of your visit. If we hadn’t done this, as you moved around the site, the portfolio pieces on the home page and portfolio page would change perhaps causing disorientation. Our portfolio page and home page were synchronized so that they would contain the same set of 6 portfolio pieces — whichever happened to be chosen for that session.

Moving from the proof of concept to the real build, we used the rekapi library to configure the keyframes and animation.  This library specifically helped us transfer from our original code by using rekapi's experimental support for dynamic CSS animation generation. CSS animations offload more of the animation to the browser allowing for greatly improved performance.
rekapi.com



As you remember, using CSS 3D Transforms, the objects come to you rather than you traveling to them. Each object’s coordinates would change dynamically, so that they moved in unison, while the particular piece you were traveling to would appear centered on the screen and than pause for a set period of time. We also wanted to avoid clipping (traveling “through” the piece you were just focused on) — so we decided to incorporate a nuance of the animation allowing the camera to “back up” and then fly around the object, which looked and felt a lot better. The blur css filter is supported in the latest webkit based browsers, which was really cool because we were calculating the blur value dynamically based on object position — the further away they were, the more blurry they would appear (true depth of field!). Firefox and IE do not support this css feature yet. The lack of dynamic blur with the static blurred images still gave a favorable experience, which meant we could keep the animation in Firefox and IE rather than using a fallback visual construct that we implement for unsupported browsers.


Conclusion

After Effects proved to be an invaluable tool throughout the process, allowing me to block out the scene and quickly reposition things — showing a preview of the final result. We didn’t have to try random positioning values in the code to develop the scene. I couldn’t imagine having to use the guess and check method in order to develop a field of ~80 objects in code. The ability to take numerical data from After Effects and implement it directly into the code saved hours of time. We will certainly be using After Effects for future 3D animations. The entire process was a great learning experience in learning how far our web development team could push CSS 3D Transforms with today’s browser performance, as well as finding short term workarounds to render the animation as desired (creating the dummy objects, and positioning them in a way that didn’t fry the browser performance when it tried to render the blur filter dynamically on screen).

Additionally, allow me to mention the questions we asked ourselves in the beginning. Would camera orientation change along a given path? (no, but maybe in the future - it leaves us room for future iterations) What were the most appealing blur levels? (Just past the point of not being able to read the text on various objects behind the one you were focused on), What was the appropriate perspective, and how many objects will there be? (We went with 800px of CSS perspective, and we ended up with 86 objects). Would the camera’s paths be static and determined before hand, or dynamic and random? (Static, and determined beforehand). Which possible paths are visually interesting? (Ones that incorporate movement that involves passing a fair amount of objects before arriving to your destination. Change on Z was obviously the most intriguing since its a crutch of 3D space and movement). Of the possible paths, which perform best? (Any path that was traveled on had to ensure no more than 5-7 active objects would appear in view in the browser window at any given time, or performance would suffer). How will we iterate our 18 most recent portfolio pieces throughout the field of objects? (We used PHP and Javascript to populate the objects with our portfolio pieces) How many objects could browsers (and devices) handle in a given view? (Once we solved our problem by using dummy objects, the browser window could handle more than we needed - around 12-20).

As browser performance gets better, our Bozeman team can continue pushing theboundaries of website design with our home page concept, experimenting with changing camera angle along a path, randomizing paths, increasing the number of objects, and even randomizing fields of objects based on sets of requirements. It’s even possible that we can allow users to navigate their own path through our portfolio pieces — our step into a 3D world will provide us with much flexibility and room for improvement in the future. The experience of building our website home page animation — its dynamic and interactive nature — provides us with much inspiration for utilizing what we’ve learned for not only animations, but truly inspiring online experiences in the third dimension. One day, we will be able to move beyond “effects” and “animations” and create truly riveting immersion online. At JTech’s Montana office we are excited to continue our pursuit of custom, interactive web projects, and we look forward to the possibilities of CSS and JS-driven virtual online experiences!

A subsequent blog post will explore the coding aspect in greater depth.

Monthly inbox insights.

Our articles are published for free on our blog.
First Name
Last Name
Email Address