Welcome to the first part of the article about the After Effect / CSS 3D Transform transitions workflow : After Effects to CSS 3D workflow – Part 1 – Introduction.
Click here to see the main page of the article : http://www.turbodrive.tv/blog/css-3d-transitions-workflow-using-after-effects/
Part 1: Introduction and CSS
You need some (at least basic) knowledge to follow and apply comfortably explanations :
- Adobe After Effects: UI, expressions and scripting
- Tweening principle
- Real-time 3D principle
I try to give details on tricky parts but don’t come back on basics. It already exists a lot a ressources about these topics on the internet. Take a look at the about page to get links for learning general stuffs like these. Despite that, if you need extra clarification or feel it should have few on some points of the article, drop a line in the comments!
I’ve made the first version of this workflow when I thought about the adaptation of my Flash personal website Turbodrive in HTML5. The main ideas were :
- have something close to the Flash version for the 3D transitions
- take the occasion of the HTML5 to make the website mobile-compatible and take advantage of the touch screens to improve the user experience.
Scene used as example for the AE to CSS workflow
Compared to Turbodrive, I introduce here a simplified scene for the purpose of the example. In following the explanations you’ll be able to recreate this scene, and so, learn the workflow principles to make it your own.
After research and tests, the workflow is based on a set of tools.
CSS 3D Transforms
Compatible with modern browsers, including mobile. Only IE doesn’t support (IE 11 in september 2014) some required features in here. Android browser older than KitKat could have some difficulties too.
Especially, there is a great gallery example, which is typically the kind of thing I was looking for my needs of camera transitions. This lib has contributed to chose the CSS 3D Transforms solution.
Here is the github page of the project : https://github.com/boblemarin/Sprite3D.js
Sure Target principle
Sure target is an After Effects plug-in made by VideoCopilot. This one is pretty interesting in the way you focus on the position of the targeted 3D elements and it interpolates (tweens) camera’s transformations between these targets.
It works with a progress factor defining the camera evolution on a path made by the 3D targets. This progression is only one linear dimension. So in theory it’s compatible with controls such as scroll or touch move (here I’m gonna use a range-input).
You don’t need this plug-in to follow the workflow. I’ve kept the principle of Sure Target only, and you’re gonna code a kind of home-made Sure Target which fit better to our 3D Scene (and the way it’s built).
Adobe After Effects
The software is kind of close to CSS in the way it manages the 3D elements. There is no built-in modeling tool and it’s based on solids (planes) and bitmaps, or other 2d footages… You can especially take the advantages of this powerful UI and features such as layers, nested compositions, timeline…
The AE scripting system in JS allows to effectively add features to the software. You’ll use it to export data in JSON and then manipulate it in the HTML5 project.
In short, it’s easy to go from AE to CSS 3D Transforms.
Instead of AE, I’ve thought about developing a tool made in JS, but it would take longer to build it as much functional as AE.
Workflow setup steps
Pros / Cons
- Wider browsers support than WebGL
- 3D pages made in CSS are still crawlable by search engine robots.
- Accuracy in locating elements in space : you focus on transitions, camera movements and layout.
- Touch move compatible (and accelerometer too, even if not directly related)
- AE is dedicated to motion design. It’s full of the features you want.
- CSS is pretty lightweight for small 3D scene
- You need AE and knowledge about how it works.
- The AE setup could appear a bit complicated.
- The camera follows a path, so it’s guided and there is no totally free movements.
- CSS 3D Transforms are limited (the skybox for example, isn’t very well supported on some browsers)
To make explanations simple, let’s use some conventions.
- AE means one or several element(s) (null object, composition, ) in After Effects.
- FCameraCSS, it’s a generic term I use for the CSS setup enabling to transform the 3D point of view.
- FCameraAE means the 2 layers in AE which behave in the same way as the FCameraCSS. It’s composed by a null object and a composition to recreate the property
rotateFirstenabled of the Sprite3D.
- targetsContainer is pretty similar to FCamera, but in this case it’s mentioned as a container only (a composition in AE or a Sprite3D in JS).
- targetsContainerAE means the composition itself while FCameraAE includes the null object.
- targets3D are the 3D elements targeted by the FCamera. Commonly they are also the container of the website pages, spread out in 3D space.
- target3DCSS means a Sprite3D with
- target3DAE means a combo of 3 layers (2 null objects + 1 composition) to recreate the behavior of a Sprite3D with
- target3DController is a null object, located in interactiveContainerAE, linked to a target3D and used to control this.
Setting up the 3D Scene with Sprite3D.js
Let’s organize directly the 3D Scene and study the Sprite3D.js specificities. You should understand the 3D CSS Transforms logic to bring it toward AE, and then, extract data from AE to CSS.
The scene is directly inspired by the gallery example. It’s precisely the way this scene has been made which provides a camera behavior in CSS, though there is no camera in CSS.
Actually, a important feature of Sprite3D.js contributes to have this fake camera behavior (= FCameraCSS) : the
setRotateFirst() method. This essential method is only available in an old Sprite3D.js version. You can download this here : http://minimal.be/lab/Sprite3D/js/Sprite3D.js. This is the one I use in this article.
This well-named method provides a way to define in which order you want to apply 3D transforms : translations or rotations first (since the 3D transformations perform differently depending on this order).
setRotateFirst(false) or default └─> translate3d(x,y,z) rotateZ(rotZ) rotateY(rotY) rotateX(rotX); setRotateFirst(true) └─> rotateX(rotX) rotateY(rotY) rotateZ(rotZ) translate3d(x,y,z);
The key of the gallery example above is basically :
- A main Sprite3D container, with rotation transformations applied first. This container is put on the stage (kind of “global” or “super” container).
- Several Sprite3D, nested in the main container, all of them with different positions and rotations and all of them with the
rotateFirstvalue disabled (default value).
- To get one of the child Sprite3D flat centered on screen, we take its coordinates and give their opposite values to the main Sprite3D container. In this way, and in the local space of the targeted child, the main Sprite3D container “cancel” the 3d transformation.
All of the nested div must have the property
transform-style with value as
preserve-3d, to preserve the 3D transformation of each of their parent div. It’s automatically defined by Sprite3D.js.
This property doesn’t work currently with IE 11 (nor in previous versions). It flattens 3D transformations in nested DIVs.
Let’s code now!
Quite simple in HTML, with a 2D DIV
id="scene3D" where I put the 3D stage inside. It’s not a mandatory DIV, it’s only to make the setup clean and isolate 3D stuffs from 2D elements.
Then, there is a pretty obvious DIV
id="page-template". This is the page template used for the targets3DCSS. I’m gonna create 4 targets3DCSS based on this template. Each of them with a different color and displayed name (in the example “Page N”, with N as the page number).
For the beginning, everything is based on a 1280x720px viewport. As well, the size of each elements will be defined in relation to this viewport size. It’s pretty convenient to start like this. I’ll explain in the part 2 why I work in this way. It’s not “mobile first”, but in the last part I’ll show you how make the size of the content flexible and so, make the scene responsive. You’ll chose between fill out the window, keep or crop some areas of your content…
I’ve also created some 3D elements, without Sprite3D.js. These are pretty simple and they don’t need the use of the library. In the case you want to do the same, don’t miss to specify the famous
The font is available here: http://www.fontsquirrel.com/fonts/tex-gyre-adventor
The JS part is based on the gallery example with enhancements for the project specificities. Basically, you add the “Sure Target” logic to the FCameraCSS.
I don’t create a stage + a main container, but instead, a stage + interactive container + main container, all nested. The name for each of them is : stage, interactiveContainer and targetsContainer.
StageCSS is the Sprite3D which contains the whole scene.
TargetsContainerCSS is the container providing the camera behavior. This is the one taking the opposite value of the elements you want to target.
InteractiveContainerCSS provides two features : tweaking the 2D viewport position and use the accelerometer independently of the targetsContainerCSS.
Quick explanation about the interpolation function. It’s important as everything work on it, in JS and in AE.
This function is driven by the range-input. When the user manipulates the slider, it changes the progress factor value (let’s call it
globalCamProgression) and it updates the targetsContainerCSS transformations.
The function takes only one parameter. It’s a string which is the name of the transformation properties you want to interpolate (in this case they are : “x”, “y”, “z”, “rotationX”, “rotationY” and “rotationZ”).
The targetsContainerCSS transformations depends on the targets3D with the nearest ID of the current
globalCamProgression value :
globalCamProgressionis an integer and you get the target values for the calculation
- or you get the 2 nearest targets and interpolate linearly their transformation values using
globalCamProgression(take a look at http://en.wikipedia.org/wiki/Linear_interpolation to know more)
The function return the opposite number when the calculation is done, in the same principle as the gallery example.
The remaining JS code shouldn’t give any difficulty. The several transformations of stageCSS and interactiveContainerCSS in the
createScene() function are the results of tries for cross-browser compatibility.
Temporarily, I feed the scene with randomly placed targets3DCSS. You’ll see later how to change this with AE.
The whole JS file :
Et voilà! You should have a 3D Scene working, pretty close to the gallery example excepted that you control the FCameraCSS from a range-input instead of using a tween engine from one target to another.
Obviously, tweening between 2 targets is still possible and even advised (in the case you want to go from Target 1 to Target 3 and avoid going through Target 2). In our case a linear navigation is required to make it work by swiping the screen.
Click here to see the demo of the current scene: http://www.turbodrive.tv/arcade/workflow_aetocss_p1/
In the next part of the article, you’ll transpose the actual CSS 3D Scene into AE and I’ll answer some questions such as the relation between focal length and CSS Perspective property.
Ultimately you’ll learn how to create a data exporter for targets3DAE and other 3D elements (like the small white cubes) from AE.