Frame by Frame Animation with SVG

John Mannix

John Mannix, Technical Director, Governor Technology Limited

View all articles
Article Image

Introduction

A little while ago I worked on a joint project with Microsoft and Orange where we wanted to animate a crowd of people walking into a stadium as part of an infographic about an event. Part of the brief on the project was to make use of new HTML5 features in IE9, so we built the animation using SVG sprites rendered onto HTML5 canvas, and found that the technique worked really well.

Fast forward about eighteen months and I decided it would be a nice thing to revisit with the aim of producing a blog post on the technique. However, the web being what it is, things have moved on a bit since then, and what I ended up writing about was a little bit different.

The critical thing that has changed, and that persuaded me to pursue a slightly different angle for the blog post, is that many browsers now support SMIL animation elements in SVG. That means you can create SVG images which animate automatically in the browser and therefore bypass the need to draw the animation frames into canvas.

The rest of this article explores the process I went through to create a pure SVG animation of a silhouetted character walking amongst trees at dusk. You can see the final animation here.

Creating the character animation

The first thing I wanted to do was create a realistic animation of a character walking. I looked around the web for something suitable but couldn't find anything readymade that fitted the bill, so I turned to a technique I've used before in Flash called rotoscoping. Rotoscoping is an animation technique in which you trace over video footage frame by frame to create a realistic animation. At its finest it can be used to create incredible animation like that featured in A-ha's 1980s classic video for Take on Me, but my ambitions were a lot simpler. My plan was to find a video of somebody walking and trace over the frames to create a vector silhouette capturing the realistic walking motion of the original.

Most stock photo sites now do video clips as well as images, so I spent a bit of time searching and found a suitable clip of a woman walking on Shutterstock. Flash is still a good tool for doing the rotoscoping, even though we're ultimately going to export the frames to SVG, so I used Adobe Media Encoder CC to convert the original clip in mp4 format to flv.

The next step was to import the video into Flash so that it sat on the timeline and played on the main stage. You do that by using File->Import->Import to stage, pick the .flv video file and then select Embed FLV in SWF and play in timelinefrom the dialog that pops up.

clip_image002

To create the vector animation, I isolated a single walk cycle and created a series of keyframes in a second layer over the original video layer into which I then traced over the video frames to create the silhouette.

For each frame I used a Wacom tablet and the brush tool in Flash to outline the character, and then the paint bucket tool to fill in the silhouette.

clip_image004

It's a little bit of a painstaking process to do this for thirty odd frames, but the end result is you can switch off the video layer and you get an animated silhouette of the walking figure moving across the stage.

To tidy things up a bit I used the onion skinning tool in Flash to clean up the frames and move them over each other to make the character walk in place.

clip_image006

The final step was to shrink the stage down to crop the character closely and I was ready to look at exporting the animation to SVG.

Exporting to SVG

Flash doesn't have a built in function to export to SVG, so last time I did this I had to copy and paste the shapes into illustrator and save them to SVG from there. But that wasn't working for me with the latest version of Flash so I cast around for a better option and found a Flash extension called Flash2SVG that did the job. You can download it here:

http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=2422028

The extension adds a new window (Window->Extensions->SVG) that contains all the property settings and the export button. One of the options is to export all the frames in the current timeline direct to an Animated SVG, which was perfect for what I wanted - so a few tweaks to the settings and a click of a button and I had an SVG file of the complete animation ready to go!

clip_image007

The exported SVG file contains all of the frames as groups, and for each frame it embeds an SMIL <animation> element which switches the individual frames on and off in a timed sequence to create the animation. Opening the SVG animation in a browser automatically plays the animation without the need for any further scripting.

Putting it together

Armed with an animated silhouette of a lady walking, it just remained to put that together to make a compelling demo. Looking around for inspiration, the idea of making the silhouetted character walk amongst a scene of trees silhouetted against a sky at dusk formed in my mind and I started to pull the demo together.

For the trees I download a vector image, again from Shutterstock, of various treelines and exported one to SVG using Illustrator. I then put some simple HTML together to place the SVG trees at the bottom of the browser superimposed against a gradient background to create the sky at dusk. The gradient sky is done with CSS gradients:

        body {
        margin: 0;
        height: 100%;
        background-color: #102b58;
        background: -webkit-gradient(linear, 0%, 0%, 0%, 100%, from(#0e2a59), to(#f3732d));
        background: -webkit-linear-gradient(top, #0e2a59, #f3732d);
        background: -moz-linear-gradient(top, #0e2a59, #f3732d);
        background: -ms-linear-gradient(top, #0e2a59, #f3732d);
        background: -o-linear-gradient(top, #0e2a59, #f3732d);
        background-attachment: fixed;
        }
      

Finally, to make the character walk across the screen from right to left I used some simple JavaScript and requestAnimationFrameto move the SVG element across the scene at the right speed. It's important to use a time based reference to calculate the position of the character rather than doing a fixed number of pixels per frame because different browsers on different machines will run at different frame rates, so using the time to calculate position guarantees a consistent experience.

        var startTime = Date.now();

        function step(timestamp) {
        var person = document.getElementById("person");
        var offset = (Date.now() - startTime) / 16;

        if (person != null) {
        person.style.right = (offset - 55) + "px";
        }
        if (offset > window.innerWidth + 55) {
        startTime = Date.now();
        }

        requestAnimationFrame(step);
        }

        requestAnimationFrame(step);
      

clip_image009

Browser compatibility

Now, it wasn't all as plain sailing as it sounds from my description above. In practice there were the usual browser quirks to be worked around.

For a start, no version of IE, not even the upcoming IE11, has support for SMIL animation in SVG, so in IE the character drifted across the screen with all of the frames visible simultaneously looking like a ghost gliding through the forest. Luckily I found a polyfill for SMIL that implements animation support in JavaScript for IE. The polyfill is called Fake Smile and you can download it from:

http://leunen.me/fakesmile/

To use it you embed a reference to the JavaScript file within the animated SVG and make sure it is included in the HTML using an object tag rather than an img tag, and viola - the animation magically comes to life in IE10.

There were also some issues with Firefox - the SVG background was blurring if it was resized and the performance was slow. To fix that I had to re-export the trees at a larger size, remove the width and height attributes from the SVG file and tweak the CSS to make sure the trees were not being scaled. That seemed to pick up the performance, although it is still slower than Chrome.

And on top of that the animated character did not show at all in Chrome or Safari. That turned out to be a combination of the fact that I needed to tweak the shim for requestAnimationFrame and that Safari has a bug with scaling SVG imported using an object tag. That was fixed by again removing some fixed sizes from the SVG file.

Summary

I'm really pleased with the results. I can see that this technique could be used to add visual interest to web pages or animate things like infographics. And because it is using vector graphics, you can scale the animations dynamically, making it suitable for responsive sites where you need your animations to resize with the browser. The final animation works well on pretty much all contemporary browsers including: IE, Firefox, Chrome, Safari and Opera on the desktop, and Windows 8, iOS and Android on tablets and phones as well!

The source code for the blog post can be downloaded from bitbucket here: https://bitbucket.org/governortechnology/svganimation

Post a comment
Your Screen Name
Your Email Address
Your Comment
Recent