Animated SVG Icons with Snap.svg

Using SVGs on websites is becoming more and more easy with great libraries like Snap.svg. Today we want to explore what we can do with it and animate some SVG icons as a practical example.

AnimatedSVGIcons

View demo Download source

SVG has been one of the most underused technologies when it comes to web development. Despite it’s usefulness and powerful possibilities it’s still a mystery to many and when it comes to integrating it and using animations, many developers don’t know where to start. With great libraries like Snap.svg the use of SVG assets becomes more easy and today we’d like to explore how to animate SVG icons.

You’ve surely seen some great examples of animated icons using CSS transitions and animations like the Navicon Transformicons by Bennett Feely which were explained in this excellent collaborative tutorial by Sara Soueidan. We want to try to do something similar using SVG icons with the help of Snap.svg.

Please note that we are working with a modern JavaScript library for manipulating our SVGs. Older and non-supporting browsers will not be capable of all features.

The first thing we do is to create some SVG icons using an SVG editor like Inkscape. We used a size of 64×64 pixel for the icons.
Inkscape

For each icon we want a special animation to happen. For example, for the zoom icon we’ll want to scale up the plus path. We’ll define what will happen for each icon in our script.
We’ll add the icons dynamically to our page using Snap.svg and if SVG is not supported we’ll simply show a background image for the span elements that we use to wrap each graphic:

<section class="si-icons">
	<span class="si-icon si-icon-play" data-icon-name="play"></span>
	<span class="si-icon si-icon-monitor" data-icon-name="monitor"></span>
	<!-- ... -->
</section>

With the help of Modernizr we can define the fallback in our CSS:

.no-svg .si-icon-play { background-image: url('../png/play.png') }

.no-svg .si-icon-monitor { background-image: url('../png/monitor.png') }

The PNG icons were generated with the fabulous iconizr tool. You could as well use CSS sprites and define a active class but we decided to just do a very simple fallback for this demo.

If you add the class “si-icon-reverse” to the span, the icon will be initially rendered with the reversed “shape”. For instance, if you want to display the stop icon rather than the play icon, you can achieve that in the following way:

	<span class="si-icon si-icon-reverse" data-icon-name="play"></span>

Now let’s take a look at what we are doing in the JavaScript. The idea is to do something with each icon. That can be some kind of transformation, like a rotation or a scale, or a change of a path altogether. With the Snap.svg we can dynamically load our SVGs, which we store in a folder, and manipulate them in a very practical way thanks to the powerful API.

The configuration variable for the icons, “svgIconConfig” has all the animation settings for each icon.
Let’s take a look at its logic:

[icon name - same name given to the data-icon-name] : { 
	url : [url of the svg file],
	animation : [array of animation configs for each element]
}

Each animation config can have the following structure:

{ 
	el : [element selector], 
	animProperties : [animation config for the initial/from and final/to state]
}

Let’s take a look at some possible values for the initial and final state:

from : { 
	val : [animation name value pairs],
	after : [attribute name value pairs to be applied when the animation ends],
	before : [attribute name value pairs to be applied before the animation starts],
	delayFactor : [animation delay factor],
	animAfter : [animation name value pairs to be applied when the animation ends] 
}

A real example would be the following:

myIconName : { 
	url : 'svgs/myIconName.svg',
	animation : [
		{ 
			el : 'path:nth-child(5)', 
			animProperties : { 
				from : { val : '{"path" : "m 61.693118,24.434001 -59.386236,0 29.692524,19.897984 z"}', animAfter : '{"stroke" : "#000"}' }, 
				to : { val : '{"path" : "m 61.693118,24.434001 -59.386236,0 29.692524,-19.7269617 z"}', animAfter : '{"stroke" : "#444"}' }
				} 
		},
		{ 
			el : 'rect:nth-child(3)', 
			animProperties : { 
				from : { val : '{"transform" : "t0 0"}', after : '{ "opacity" : 0 }' }, 
				to : { val : '{"transform" : "t-10 -10"}', before : '{ "opacity" : 1 }' }
			} 
		}
]
}

You can initialize the icons like this:

new svgIcon( element, configuration [, options] );

And these are the possible options:

{
    speed : 200, // animation speed
    easing : mina.linear, // animation esing
    evtoggle : 'click', // event: click || mouseover
    size : { w : 64, h : 64 }, // size
    onLoad : function() { return false; }, // callback on svg load
    onToggle : function() { return false; } // callback on toggle (click or mouseover/mouseout)
}

Check out the demo to see some examples for different sizes, easings and activations (on click and on hover).

We hope you enjoy this experiment and find it useful!

View demo Download source

Previous:
Next:

Tagged with:

Mary Lou (Manoela Ilic) is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://tympanus.net/

Related Articles

Feedback 70

  1. 1

    Hi there,

    first of all thx for the great work. Trying to animate a single icon on my personal website I ran in some issues. As I am far away from being a JS pro I think your scripts in the demo focusses on having multiple animated icons in a website. Till now I am unable to transform your code to make it work for one single icon/element.

    Would love to get some help on this.

    thx
    David

  2. 4

    Wow!
    This article gave me courage to look into snap svg!
    thanks you

    my share: instead of external loading svg, one can include a sprite once and than get the icons element by Id localy.

  3. 5

    When I open the source of this project and open the index.html I don’t see any icons. Do anybody know why?

    • 6

      I’ve got the same problem. It says “Uncaught TypeError: Cannot read property ‘type’ of null ” on the SVGs.

  4. 7

    Love this SVG tutorial!

    Is that possible to have 2 events – like when hover on a hamburger, it expanded, but when it click, it cross. But it is the same SVG. How to achieve this? Could you provide an example? Thank you so much~~

  5. 10

    Finally got it working! If you letting it run locally and not on an external server under Windows you have to enable IIS under “Control Panel\Programs\Programs and Features” then click on “Turn Windows features on or off” and tick “Internet Information Services”. After that windows search “IIS” and open the application. Then under you Computer’s name (upper left hand side) und “Sites”, rightclick and “add website”. there define a name, path to your folder on your PC and define a hostname, e.g. “myicons.localhost”. access that hostname in your browser, e violà, the icons are being displayed now. It all has to do with JS being prevented locally from running due to a general risk of running malicious SW.

  6. 11

    Hi thanks very much for this tutorial. I am very new to SVG and I am just not sure if I am missing something. What are the possible values inside the val? Such as: ‘{“transform” : “r0 32 32″}’, what does that r mean?

  7. 13

    Sorry, but I find these animations very jarring, especially the one that goes from the “Menu” button into an “X”. It’s the same click with two different meanings.

  8. 14

    Great work… but it doesn’t work for me… at least the demo that I have downloaded :S….

    it seems like something is wrong: /svg/equalizer.svg. Received an invalid response. Origin ‘null’ is therefore not allowed access.

    Thanks

  9. 15

    Should it work on the latest Chrome?

    I have Version 37.0.2062.120 : No icons show.

    Works on Firefox though. Why not Chrome?

Follow this discussion

Leave a Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>