Smiling for some reason
Animating SVG elements with the possibilities built in the language, with SMIL, might raise a few questions. The specification was once deprecated, and even if the decision did not stand, it might be enough to warn and scare people off. As you explore the syntax, it is also easy to stumble on features which just don’t work, or again work differently on different browsers.
At the end of the day, some can justifiably ask: “why?”
I can think of several answers, but the most convincing argument might be an example, or two, of what SMIL allows.
And to keep the discussion practical, I can think of no better example than SVG icons.
Consider the icon for a soft heart.
In and of itself, the <path> element and its rounded edges make for a captivating picture already — you can pair the visual to a button and develop a favorite feature. With SMIL animation, however, you can build on top of this perfectly functional piece and have the heart really beat.
Leaving the <path> open, add a <animateTransform> element right within.
<path d="M ...">
<animateTransform />
</path> There are a few prescribed attributes, and you might have seen a handful in a separate introduction to the topic. attributeName and type help to target the transform attribute, with the specific value to scale the shape.
<animateTransform
attributeName="transform"
type="scale"
/> dur describes how long the animation should last, and to the value the animation should take.
<animateTransform
attributeName="transform"
type="scale"
dur="0.5s"
to="1.15"
/> The whole is enough to resize the heart, gently and over time. The only hiccup: the animation starts immediately, reaches the larger size and reverts back to the original design, abruptly.
Past the to attribute, pointing to one value, you can specify a few with values, separating the sizes with a semicolon.
-to="1.15"
+values="1; 1.15; 1" From 1, to 1.15, back to 1, you bring the icon to life. Pair the whole set with one, impressive attribute, begin, and you can wait for a click event to start the remarkable feat.
<animateTransform
begin="click"
...
/> The process is a tad imperative, but definitely worth the effort. You can tap the heart to have it grow and shrink.
And grow and shrink again. Behind the scenes, I couldn’t help adding a few more attributes, just to show off. repeatCount helps to repeat the animation, twice.
<animateTransform
begin="click"
repeatCount="2"
...
/> Past that, and you might have noticed a subtle difference if you decided to code along. calcMode and keySplines set up a different timing function. An easing curve to change from the default, linear motion. But I’ll let you explore the syntax for those on your own.
There’s only one attribute left, restart. I hope you’ll forgive me setting a value of whenNotActive, a small safeguard to make sure the animation doesn’t start from scratch the moment you try multiple clicks, in rapid succession.
<animateTransform
begin="click"
repeatCount="2"
restart="whenNotActive"
...
/> The animation is remarkable, and while the syntax seems excessive — you do need a heaping of attributes — you’ll soon appreciate just how much you’ve learned already. Just how many animations you can pull off by tweaking the existing code.
Consider two celestial bodies. A crescent moon and a radiant sun.
To rock and the moon back and forth you can repeat the <animateTransform> element in the context of the moon.
<g>
<!-- ...moon -->
<animateTransform ... />
</g> Target the rotation instead of the scale. Target the rotate portion of the transform attribute.
<animateTransform
attributeName="transform"
type="rotate"
...
/> Update values to change the angle to an arbitrary, possibly greater, integer.
<animateTransform
attributeName="transform"
type="rotate"
values="0; 35; 0"
/> And the rest is good as is. You can tinker with the duration and keep the begin attribute, to start the change at the lightest touch. But you might want to remove repeatCount if you believe one tilt is more than you can bear.
Moving on to the sun, you need to modify the syntax even less.
<g>
<!-- ...sun -->
<animateTransform
attributeName="transform"
type="rotate"
...
/>
</g> The rays are sketched around the center in increments of 45 degrees. This means you need just one value, the to attribute, pointing to the specific angle.
<animateTransform
attributeName="transform"
type="rotate"
to="45"
...
/> 45 degrees or a multiple of 45 if you feel so energized. You can rest assured that, when the animation ends and jumps to the starting angle, the change will be immediate, imperceptible. You can repeat the animation smoothly once more. Or as many times as you need to cheer up.
I might have hinted at it earlier, but I do hope you’ve tried the code yourself. And if not, that you’ve tried to eagerly tap the screen for a jolt of motion.
Truth be told, you can very well animate the icons with CSS, barring the begin attribute and the click event. But even if this tidbit might discourage you, the point brings me full circle back to the original quandary: “Why, oh why? You even mentioned it now, can’t I just use CSS?” . You might, and I look forward to the day the language grows and includes all of the features detailed in the SMIL spec.
In the meantime, however, you can build on solid foundations, on crisp vector graphics. You’ll be following an official specification, learn plenty more about SVG, and entertain yourself with the endless possibilities of the many elements, the many attributes you can now animate.
I am sure the process will excite you enough to spark new ideas and create something positively charged.