An Intro to SVG Animation with SMIL

Sitepoint recently posed a challenge to recreate this fun gif animation in code:

It looks deceptively simple, but it's hard to do without a lot of keyframes. My mind jumped to SVG, and I've been wanting to give SMIL a shot. I didn't find many resources on SMIL out there, so I thought I'd share what I learned.

WTF SMIL?

SMIL, Synchronized Multimedia Integration Language, is a markup language you can use to animate SVGs without CSS or JS. Because SVG is vector-based, with SMIL you can create more complex animations than what's possible with CSS and DOM elements. There is one big downside to SMIL: it's not supported in any version of IE. Every other browser supports SMIL through several versions.

Shape tweening with SMIL

To recreate the gif, I broke it into individual frames. I plugged the image into gifexplode.com which spat out this image:

The shapes tween from square to diamond to triangle to circle and back to square. The colors also transition from green to blue to red and back to green.

I wanted to write the SVG shapes by hand, so I created the four major shapes: square, diamond, triangle and circle. An SVG with a viewbox of 100x100 keeps the coordinates easy to work with.

The syntax for animating a path is like this:

<svg viewbox="0 0 100 100">
  <path>
    <animate/>
  </path>
</svg>

Add attributes and values to the animate element to define the animation. Here's the code for tweening a square into a triangle.

See the Pen An Intro to SVG Animation with SMIL - Example 1 by Noah Blon (@noahblon) on CodePen.

The animate element has 4 attributes:

The values list is where the real magic happens. The list contains any number of paths definitions, and the animation tweens those paths over its duration. I ran across a few limitations though.

The paths need to have the same number of vertices. When the animation runs, it tweens the vertices in the order they appear in the definition. If the number of vertices doesn't match, the animation won't run. It jumps between the start and end. I defined each shape with four vertices and made sure the position of each vertex matched up with how I wanted the animation to run.

In the square to triangle demo, the first vertex of the square is at its upper left corner. The first vertex of the triangle is at a point in the middle of its left edge. SMIL tweens the position of this vertex, collapsing the upper right corner of the square down into the side of the triangle.

I was only able to tween paths with curves defined with beziers -- the C and Q commands. In SVG, you can define curves in several ways, but I was only able to animate paths with bezier curves. In my experience, Illustrator outputs arcs in the bezier syntax, which makes this easier.

Reticulating Splines...

See the Pen An Intro to SVG Animation with SMIL - Example 2 by Noah Blon (@noahblon) on CodePen.

I've added the remaining coordinates for the animation to tween. Each set of coordinates is a stop along the way of the animation. All the stuff between the coordinates is figured out by the browser. In some places, I've defined the same shape consecutively. This is so the animation pauses on this shape.

There are also new attributes:

Animating the SVG fill color

Among other things, SMIL can animate fill color. Define another animation element within the path to handle the color change. The technique is the same as the path tween, except the values value is a list of colors instead of path definitions and the attributeName is fill instead of d. I've made the easing, duration, and number of values the same as the paths animation to make it easier, but it doesn't have to be. Here's the finished product!

See the Pen An Intro to SVG Animation with SMIL - Example 3 by Noah Blon (@noahblon) on CodePen.

And here it is next to the original gif:

See the Pen Sitepoint Challenge #1 in SVG and SMIL by Noah Blon (@noahblon) on CodePen.

The animation isn't exactly like the original, but it's pretty darn close. Improve it by adding additional paths definitions and more precise easing to hint the browser to the proper tween. I like the simplicity of this code as is. There are other intriguing SVG properties such as rotation and translation that can be animated with SMIL.