How i built Comme des bêtes

In this article, i will expose some techniques i’ve used to create Comme des bêtes‘s interactive web documentary with HTML5, CSS3 and Javascript.

 

 

Summary of the project

The project is entirely build using HTML5, CSS3 and Javascript. I used a lot of open source libraries and tools to make my job easier and to speed up development time. I’ve used Bower as my javascript package manager and Grunt to package my application. If you don’t use Grunt, i suggest you to read Improve your workflow with GruntJS and Automating spritesheet creation with GruntJS on my blog to learn this invaluable tool to add to your skills set.

All my Javascript files are bundled into two files. One merging all libraries and one containing all my project logics. I’ve used open source libraries like: Modernizr, PreloadJS, SoundJS, Crossroads.js, mustache.js, js-signals and ZeptoJS, just to name a few. I’ve also used Browserify as my dependency manager for my project logics.

Less has always been my CSS preprocessor of choice mixed with less-normalize and Less Hat.

All source images are saved to retina resolution, then scaled down to normal, saved to a distribution directory and minified with grunt-contrib-imagemin. Spritesheets are bundled for both retina and normal resolutions using the same technique and grunt-spritesmith.

Finally, all production assets (images, spritesheets, stylesheets and scripts) are revisionned on each build to prevent client side caching.

Video Playback

Video playback as not been as challenging as i’ve first tough. I experienced a lot of video playback issues in fortmcmoney.com and i was expecting as much issues using HTML5 video. To my biggest surprise, video playback with HTML5 in modern browser is much more stable than i was expecting.

Simply put an <video> element into your page and access is API with Javascript to load, stop and pause playback. It’s that simple. No buffer to setup or NetStream nightmare.

I have not used any video playback library in this project because video playback functionalities were not very complex. For my next project, i will use VideoJS to manage video playback to prevent some minor bugs i had when developing my own video playback script.

Audio playback

From the beginning, i wanted to use the awesome CreateJS audio library (SoundJS) to load, play and manage audio playback all over the project. Without surprise, this library was rock solid and do exactly what i expected. Recommended to everyone working with audio in HTML5 project.

Animation

Animation was one of the producers key point on this project. They wanted the best looking and smoother animations we can achieved with HTML5. So, i’ve used GreenSock Animation Platform’s (GSAP) Javascript library to easily create and managed animations all over the project. Also, every animations created uses GPU accelerated properties to ensure smooth tweening between frames and blazing fast rendering.

CSS3 Animation/Transition were only used on buttons rollover/rollout because i’m more efficient in creating complex animations by Javascript than CSS3 Animation/Transition. I’ve always found much harder to start/stop/pause an animation built using CSS3 than it is using Javascript. Maybe there is something i’m doing wrong with CSS3 Animation/Transition but Javascript serve me well and i always enjoy the end result.

Screens transitions

Next to GUI animation, a huge part of the project was screen to screen animations. Every screens on the project had a point in common; red ribbons. Ribbons are the threads through the project.

First, i tried to draw and animate theses ribbons with SVG. The result was good on desktops but horrible on tablets. Animation was jerky and suffered from many drop frames. So i drop this technique.

The next technique i tried, which as been the good one, as been to draw ribbons on canvas and animate it by redrawing the canvas on each frame. As you might have seen in visiting Comme des bêtes, both ribbons, in the transitions, are the same drawing. The top one is simply a flip on x axis of the bottom one and animated at a different rate.

When transition’s start, i draw the ribbon curve on a source canvas. Then, on each frame, draw source canvas two times onto destination canvas. The first drawing is straight to the destination canvas by using CanvasRenderingContext2D.drawImage(). The second drawing is achieved by flipping the the CanvasRenderingContext2D’s x axis using CanvasRenderingContext2D.scale( 1.0, -1.0 ). Then, draw the same source canvas onto destination canvas. Canvas is faster at drawing pixels from another Canvas than redraw complex curves on each frame. This ensure small memory footprint and fast rendering.

The next step was to create ribbons movement effect. I first tried to move the whole source canvas from left to right but it doesn’t look right.
You need to include Paul Irish’s requestAnimationFrame-polyfill.js to make this code work.

So, i get back to the drawing board and choose to create a curve drawing animation. Ribbons needed to be drawn to feel natural in a animation. I achieved that result by using CanvasRenderingContext2D.drawImage() and by passing specific parameters value.

Then, i created a transition manager that start and stop a custom transition passed as a parameter. Each transitions used different ribbons curves to create illusion of moving and transforming ribbons curves.

Conclusion

Working on Comme des bêtes as been an incredible experience. Everything work as expected right from the beginning of the project and progress goes smoothly from one step to another. Probably the first time a project goes that good from start to end. Project as been leaded so beautifully by François Le Gall that it make working on this project my best career experience so far. I hope to do more work like this in the future, so stay tuned!

Posted under JavaScript, HTML5
Tagged as Case Study

Categories