Welcome to the third and last part of the article about the After Effect / CSS 3D Transform transitions workflow : After Effects to CSS 3D workflow – Part 3 – Finalisation.
Click here to see the main page of the article : http://www.turbodrive.tv/blog/css-3d-transitions-workflow-using-after-effects/

Part 3: JS finalisation and enhancements


JSON Loading

Let’s start with the JSON file, generated by the JSX script in After Effects. The JSON object contains 2 arrays : targets and sprites3d. All of them store objects defining names, positions and rotations of the 3D elements in the scene.
Get back the main.js file seen in the first part and modify some code. It should have the scene creation, targets and controls only when the JSON file is completely loaded and parsed.

I use a function getJSON() based on XHR (http://youmightnotneedjquery.com/#json, thanks to Benoit) slightly customized.
In the callback function, there is what I had before at the initialization, I only put what is involved by the targets and JSON :

CSS Perspective

The JS file was pretty functional in the former version. So you should now have the targets3D rightly transformed in space (the same as AE) and the FCamera is following its path. I could finish here.
However, you remember probably in the last article, I’ve written about the focal length and how much it’s important to have the same value in CSS and AE. For that point, I add the function written previously to get the CSS Perspective from the focal length (28mm / wide angle in my case).

Sprite3D.js doesn’t offer to change the perspective value, so updates this directly in the styles of the DOM element of stage.

Viewport and content sizes

In the introduction, I’ve also started with a fixed viewport size, 1280×720. Pages content and 3D Transformations are related to this size and in the case of a different browser window size, it doesn’t fit at all.
Let’s start to make the viewport matching with the window size. I add a listener to the resize event of the window DOM element. I invoke the handler function just after. Then move everything you have related to the viewport size in this handler.

To resize the content, there are several options.

You can resize globally the content by re-scaling it. For example in this function, the page scale is changed to keep the ratio height/width and to not have cropped content.

In this other function, the page itself keep it scale at 100%. However, the size of the content is manually re-calculated, relatively to the viewport size (text and border size remain the same).

Feel free to adapt the solution you want. In the case of TurboDrive I’ve mixed both logics to place and resize elements proportionnally and/or relatively to the window size. For example the page background is re-scaled and buttons size is preserved when position is calculated using the window width and height.

Finally, update the perspective too, to keep the same focal length in all occasion.

Other 3D elements


The skybox is a mapped cube, created in CSS and enclosed into a Sprite3D for easy manipulation. Be careful, skyboxes doesn’t work very well in CSS. There are overlapping issues on some browser. Surprisingly, it works on iPad, so I’ve left it in the example.


Same thing than targets3D, these are elements with data exported from AE: get names, positions and rotations from JSON, initialize the HTML template, create new Sprite3D and then add it to the targetsContainer.

If you want to add complex 3D elements, my advise is to think (and build) in CSS before working into After Effects. AE should be used as a configuration tool of the 3D scene and the camera motion path, not to create 3D objects. Especially, AE has less limitation than CSS and it’s easy starting to build something too complicated to transpose in CSS.

Here is the final version :

Click here to try it in a new window: http://www.turbodrive.tv/arcade/workflow_aetocss_p3/


You’ve seen dozen of simple and useful stuffs to set up. After all, even for putting objects in space, it has been easy to duplicate and tweak the former custom controls and JSX / JS functions (take a look at the end of the part 2).

From this basis of workflow, you can imagine improving a lot of things, depending on the project you work on. You can either add for flexibility / complexity in the transitions, or add complementary features, or even try simplifying the workflow itself.
Here is a list of ideas I have about enhancements. I’ve already started exploring some, others are in progress…


A – direct transitions between targets

I’v already mentionned this possibility of tweening directly the FCamera from a target position to another, without using the Sure Target principle. It gives more freedom to the camera than following a path. Instead of using a touch move, the tween should be triggered by a common link or button. But you can use both controls for the same project. It’s what I’ve done on Turbodrive.

B – 3D elements located relatively to the path.

You can choose to place 3D elements along the camera path. In this case it’s more flexible to base the elements 3D transformations relatively to a fixed value of globalCamProgression and using the interpolate function.
Example using this feature for creating a tunnel of light between the first and second pages (AE rendering) :

C – Exporting more data

It can be useful to collect more data from After Effects : scale for example, keyframes positions or even layers3d properties deeply nested in targets3D.

Improved transitions

D – Ease inside the interpolation function

For the moment, the interpolation function used in JS and AE is linear. But you can totally add ease equations for smoothing (or bounce, accelerate, decelerate..) the FCamera evolution on the path.

Example of modified getValForProp() en JS, using a easeInOutExpo() function (get from the well known work of Robert Penner) :

Change the ease by the one you want (exponential ease could seems too strong). You can even define one different ease for each of the piece of FCamera transition between 2 targets.

E – GlobalCamProgression eases exported from AE

In the same mood as exporting more data from AE, you could export eases applied to the globalCamProgression value. I haven’t implemented this feature yet but I’ve worked on a function for converting AE eases into values usable with cubic-bezier functions.

The 4 returned values can be used

These eases are applied on the keyframes of the globalCamProgression slider itself in AE (look at the gif of the timeline in the part 2).
The effect is a bit different than the one put inside the interpolation function (the one you’ve seen just before).

Mixing eases on globalCamProgress and in the interpolation function

If you’ve placed 3D elements along the path (as seen in the enhancement B.), there is a big difference. Eases inside the interpolation function affect the elements positions when eases on globalCamProgression value don’t.

Here on the tunnel light example :

Influence of the ease running in the interpolation function

F – Smoothing the FCamera path in space

Even with eases applied previously, you can meet weird/robotic/unnatural direction changes when the FCamera comes on a target and left it. Actually eases don’t change the shape of the path. Interpolated coordinates properties have the same velocity for the 3 axis at the same time. Eases only affect the FCamera velocity on the path.
One of the solutions is to generate a 3D Natural Cubic Spline and use it as path. It works only on position, not the rotations because they are independent from the generated path.


Smoothed path with 3D natural cubic spline

This topic is pretty exciting as it brings about smooth and natural FCamera mouvement. It also allows to release the FCamera from break points created by the targets3D. I’d like to come back on this stuff soon.

G – Delinking globalCamProgression up to 6 values

For each of the properties : x, y, z; rotationX, rotationY, rotationZ, you can define a different progress factor. It enables this properties to have their own speed, delay, ease..
Also it allows to change the path shape (in the case of the position), without the use of the cubic spline. By the way you can’t use both of these methods at the same time.

Easy setup

H – Simplifying process

I know the AE setup could seem twisted. I’m pretty sure there is a way to make the same without the use of 3 nulls in more than the composition. I don’t have anything concrete about this yet. Probably using expressions and matrix3D?
Actually this point is rather a question of convenience.


That’s it for this article about the workflow AE to CSS 3D Transforms. I’ve started with something pretty simple. Using the really convenient Sprite3D.js and After Effects, you’ve seen how we can reach advanced camera transitions.
I’ve finished with the many possibilities of improvements this working method can have. Some of the point I’ve talked about will become probably the main topic of future articles. Amongst them, the 3D natural cubic splines and export of cubic béziers from AE are ones of the most interesting