Having fun with Lottie-web and Bodymovin

Making yogurts fly everywhere since 2018

Arnaud Tanielian
Team Stink
6 min readApr 4, 2018

--

Same, but with yogurt

In collaboration with Chobani in March 2018, we were asked to build a fun, little interactive page for a Flip campaign.

The concept: three different landing pages (accessible with a query string parameter), one for each part of Flipland. Each page features a unique intro animation and an iframe containing a coupon. Once the user has printed the coupon, an endless animation starts looping through the different worlds.

We took this opportunity to introduce a new type of page for chobani.com that would break away from the grid system and give us more creative freedom: an “Experience” page.

General Workflow

All the animations were done in After Effects. We wanted to be able to interact with the animated elements, but doing all the animations in code would have taken a very long time and wouldn’t have given us the possibility to have a plan B. Plus, motions designers seem to be actually good at… motion design. Working with them is always a good option 👀.

To accommodate animation feedback from the client, we decided that creating videos would be a better and quicker way to share our progress with Chobani.

The flexibility, performances, and API offered by the Bodymovin plugin +lottie-web library gave us a solid option for animating elements in JS, so we could later build interactions with them.

Finally, if anything were to go wrong, we could fall back to the video format. We would lose interactivity but we would still have wide compatibility across browsers/devices.

Motion recipe by Anthony Méric

Making yogurts fly sounds very promising, but it needs an essential ingredient: Motion Graphics! Here’s how to make the magic happen and add flavors to the experience 🍓🍎🍍.

First, the story timeline. We needed to introduce one of three key visuals to start the experience, depending on the page the user lands on. Once the coupon has been printed, the landscape breaks apart and the user is transported to the next Flip landscape.

The infinite zoom idea

Infinite zoom is back! It’s the (new) cool kid on the block. This type of transition gives users a feeling of an infinite universe that keeps on evolving. The images keep coming and fooling your eyes.

We started by looking at motion references to find the right feel for our idea.

Animation Reference — Ooohlympics by Vladimir Marchukov

On top of the infinite zoom effect, we decided to use smooth animations to reveal the landscape and stop motion on floating elements, embracing the handcrafted style of other Chobani creative.

After Effects Workflow

First, we set up worlds of assets recreating the three main still frames, ready to be animated.

Between these master Keyframes, we created the infinite zoom effect by animating the main properties Position and Rotation, used the Scale to simulate the Z Position in the space, and generated all the animation data with Bodymovin.

Infinite zoom animation

Once all the assets and the main transitions were ready, we animated each landscape once the page loaded. We used bouncing animations on each layer by shifting the timing to get smooth animations and a fast reveal.

landscape reveal introduction

The power of controllers

One of the keys of success to the animation process was to combine the “Separate Dimensions” feature in After Effects with Null Objects. The power of these features is sometimes underestimated, but they give so much more control over the animated path of each layer and save many hours of tweaking.

To reveal each landscape, the first step was to link all the layers to the Y Position of a Null Object so we could manage the amplitude of the global composition. To get more control over the secondary animations and create a parallax effect, we used the separate X and Y Positions, Rotation, and Scale of each layer.

Stop Motion

The final part was to add more character to the animation by adding Stop Motion, but only on floating elements: a bee, a cloud or the product itself.

How could we embrace this handcrafted aesthetic without animating hundred of layers frame by frame? We tackled that in three steps:

1/ We positioned only the main Keyframes, and used Wiggle Expression and Bezier Path to add a “natural” animation feeling.

2/ Then, we changed the comp to 5 fps and used the option “Convert Expressions to Keyframes”. That generated a Keyframe every 5 frames on each properties.

3/ Finally, we switched to “Hold Keyframe” to get the final Stop Motion look.

Motion Designers love Keyframes

By using this process, the mobile adaptation (portrait) was pretty straight forward. We mainly moved the X Positions of each layers to fit with the new layout, which avoided re-animating hundred of layers. So much win 👊

My best friend 🤜 🤛

Motion designers and interactive developers are best friends! We know that simply animating keyframes in a timeline and smashing the render button is not enough.

As motion designers, we don’t want to waste time and energy with repeated tasks. We want to optimize feedback iterations and use our tools to drive the quality of our ideas. For these reasons, we cared about the composition hierarchy, the asset naming, and animations setup in order to make the life of the developer easier.

Speaking of which… back to Arnaud!

Let’s code! Page Setup

We used React-Loadable to create independent JS chunks for every “experience” page. Therefore, we were free to use any specific library (in our case, lottie-web), logic, or static data, and they won’t be included in the main JS application.

Interactions hack

Me using a library called Rematrix to “hack” another library.

After fixing some paths in the data.json generated by Bodymovin, we could easily use the library to run the animation on the front-end, using the SVG render for performances/easy DOM access reasons.

We decided to implement a parallax interaction. Turns out, you can’t access the “camera” through the animation data if you’re not using the HTML render. We hadn’t found a way to access the layers through the library, sooo…we started hacking around.

Looking at the DOM, lottie-web animates the layers using the transform attributes of the<g> tags contained in the generated SVG. Once the intro animation was done, we:

1/ Set up a dictionary to associate a speed/limit X/limit Y for each elements using an id based on the asset filename.

2/ Stored a reference to each <g>, extracted the matrix value of the transform attribute, and used Rematrix to abstract the matrix so we can manipulate it easily.

3/ Set up a mouse move handler to catch the mouse position values.

4/ On request animation frame, we looped through the stored matrices, applied a matrix translate (with a different speed and value depending of the current element and mouse position) to finally set back the matrix value in the transform attribute.

Final optimizations

Bodymovin exports data and assets so it’s ready to use, but we wanted to take advantage of our CMS Contentful and its Image API, largely used on the rest of the website.

Therefore, we execute a little function on runtime that updates the path of each asset layer with the path of the same asset previously uploaded in the CMS. We adapted the format (webp/png) and size on the fly depending of the user context.

Results and take away

Our experience with Bodymovin wasn’t perfect, but very promising. We pushed it to the limit (big bitmap animations) and the front-end library delivered very good performances overall.

We can’t wait to use it for smaller animations with vectors and bring back the motion designers into the heart of the web animations, just like in the good old Flash days.

Visit https://www.chobani.com/flip/ to see the final outcome — it will be up for just a few months!

If you want to see the two other landing pages, go to https://www.chobani.com/flip/?world=1 and https://www.chobani.com/flip/?world=3.

Hope you enjoyed!

--

--

Arnaud Tanielian
Team Stink

Also known as Danetag on the Internets. Engineering Manager @ Shopify