While animating SVG with CSS is easy and comfortable, CSS can’t animate all the SVG properties that are possible to animate. For instance, all the properties that define the actual shape of the elements aren’t possible to change or animate in CSS. You can animate them through SMIL though. Sara Soueidan covers this in her guide to SMIL here on CSS-Tricks, but I thought I would shine a light on this particular ability.
Most important fact: the shapes need to have the same number of points
Otherwise, the animation will just fail. The shape won’t disappear or anything, but it won’t animate.
It’s not extremely obvious how many points a shape has just by looking at the d
(in the case of a path
) or points
attribute (in the case of a polygon) so you may just need to start in a vector editor program with a single shape and work from there.
1. Start with the most complicated shape
In this demo I’m going to morph from a star to a check. The star is more complex:
Save a copy of that SVG, then make a new copy for the next shape.
2. Make the next shape with those same points.
Drag the points around until you have your next shape.
3. Use the starting shape on the SVG shape element itself
<svg viewBox="0 0 194.6 185.1">
<polygon fill="#FFD41D" points=" ... shape 1 points ... ">
</polygon>
</svg>
4. Add an animation element that animates to the next shape
<svg viewBox="0 0 194.6 185.1">
<polygon fill="#FFD41D" points=" ... shape 1 points ... ">
<animate attributeName="points" dur="500ms" to=" ... shape 2 points ... " />
</polygon>
</svg>
That animation will run immediately, so we’ll need to fix that up a bit.
5. Trigger the animations as needed
SMIL has the ability to handle interactions like clicks and hovers, so long as all that happens within the SVG itself. For instance, you could begin the animation when it’s clicked on, like:
<polygon id="shape" points=" ... shape 1 points ... ">
<animate begin="shape.click" attributeName="points" dur="500ms" to=" ... shape 2 points ... />
</polygon>
That’s pretty neat, but it’s a little limiting since you can only handle clicks from other elements right in that same SVG. Perhaps this SVG is just a part of a <button>
and you want to run the animation on any click on that button.
First give the animation an ID so we can find it with JavaScript, and then prevent it from running with:
<animate id="animation-to-check" begin="indefinite" ... />
Now you can get a reference to that animation and kick if off how you like:
animationToCheck = document.getElementById("animation-to-check");
// run this on a click or whenever you want
animationToCheck.beginElement();
Demo
This demo actually has four animations. One to morph the star to a check, one to change the color, and then both those same animations in reverse. Clicking the button checks the state of the button and then runs the appropriate ones.
See the Pen Shape Morph Button by Chris Coyier (@chriscoyier) on CodePen.
Would be pretty cool for charts, like this old Raphael demo:
Yup and you can use the same technique for shapes cut out of HTML elements with the
polygon
function value forclip-path
– demo, change$n1
and$n2
in the SCSS to change the number of vertices of the polygons you switch between http://codepen.io/thebabydino/pen/aFrcu (WebKit only at the moment, plus a weird bug manifesting itself when there’s a solid background and I’m also animatingtransform
on the clipped element)I have also used this technique to create the illusion of a “breathing shape”, going from an n-point star to an n-polygon http://codepen.io/thebabydino/pen/Fxrbd (again, WebKit only at the moment, as IE has no support for clipping and masking and Firefox doesn’t support shape function values for
clip-path
)I like it! Would it be possible to animate first from the star to some intermediate shape and then to the check? As it is it takes me back to some early-90’s tweening. A shape in the middle (and perhaps a little “bouncy” easing? ) — something like a circle or a diamond or something — might provide a more smoother visual.
Absolutely! You can add as many keyframes as you need and the browser will figure out the tweens. You can also time the keyframes over the duration, so you can create pauses at certain times.
The key is that each shape needs to have the same number of points — or vertices. Creating and aligning those to how you want the shape to animate is the real art to this technique.
Check out my post for more info: An Intro to SVG Animation with SMIL .
Or you could use a Flash shape-tween and export an SVG sequence, import that into webframes and export a single SVG file with CSS animations. It’d hit every browser.
Ah, so cool. Animations make interfaces feel so much more friendly, and this is a powerful addition to the “typical” animations that designers put on websites. Thanks for the write up, Chris!
OMG its quite simple. A few days before when J was reserching about SVG icons I found couple of icons with some great animations, however they were quite difficult but this solution is quite easy.
Besides the limitation of changing the points only this one works for many applications.
I like it! Would it be possible to animate first from the star to some intermediate shape and then to the check? As it is it takes me back to some early-90’s tweening. A shape in the middle (and perhaps a little “bouncy” easing? ) — something like a circle or a diamond or something — might provide a more smoother visual.
I like it…simple OMG..thanks
The key is that each shape needs to have the same number of points — or vertices. Creating and aligning those to how you want the shape to animate is the real art to this technique.