svg-animation-interaction-preview
Coding - HTML5

Animation and Interaction with SVGs

One of the many advantages to using SVGs in your Web pages is that you can use standard methods to interact with the elements inside them. In this tutorial we will demonstrate animating SVG elements and using JavaScript to implement interaction with them. You can use a few approaches to animation with SVGs, but we will opt for the animate element, which is based on SMIL. We will also use JavaScript to listen for user interaction events with the shapes in the SVG, responding by changing their appearance. Finally, we will combine animation and interaction by starting an animated effect on user interaction.

Create an SVG

Let’s use the simple SVG we created in the Introduction to SVG tutorial:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body, html {background-color:#330000;}
svg {border:3px double #FFFFFF;}
</style>
</head>
<body>
<svg version="1.1"
	baseProfile="full"
	width="500" height="400"
	xmlns="http://www.w3.org/2000/svg">

<defs>
<linearGradient id="backGradient" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stop-color="#FFEEAA"/>
<stop offset="30%" stop-color="#FFFFFF"/>
<stop offset="70%" stop-color="#FFFFFF"/>
<stop offset="100%" stop-color="#FFEEAA"/>
</linearGradient>
<radialGradient id="irisGradient">
<stop offset="0%" stop-color="#006633"/>
<stop offset="100%" stop-color="#003366"/>
</radialGradient>
<radialGradient id="lightGradient" cx="0.75" cy="0.25" r="0.75">
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/>
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="0"/>
</radialGradient>
</defs>

<rect width="100%" height="100%" fill="url(#backGradient)"/>
<circle cx="250" cy="200" r="180" fill="url(#irisGradient)" stroke="#000033" stroke-width="3px" stroke-opacity="0.7"/>
<circle cx="250" cy="200" r="70" fill="black" stroke="#121212" stroke-width="2px" stroke-opacity="0.5"/>
<circle cx="270" cy="180" r="20" fill="url(#lightGradient)"/>

</svg>
</body>
</html>

If there are any elements in there that you are not yet familiar with, you may wish to work through that tutorial before you continue with this one. The SVG presents an eye shape, with various gradient fills and strokes with opacity levels specified. As you can see, the gradients are specified in a defs section and referenced within the shape attributes. We also apply a little CSS code to the SVG in the page head style section.

introduction-to-svg-final

We will add to the SVG shape code and will insert a little JavaScript in the page head as we go along.

The Animate Element

Let’s begin by adding an animate element. This method of SVG animation uses the SMIL specification, with some additions. You can add the animate element inside your SVG shape elements. Start by adding one inside the circle we use for the light reflection inside the eye pupil (with the “lightGradient” fill) – split the circle element into an opening and closing tag instead of a self-closing one:

<circle cx="270" cy="180" r="20" fill="url(#lightGradient)">
<animate />
</circle>

Let’s make the reflection appear slowly when the page loads. To achieve this we will animate the fill opacity. Let’s add some attributes to the animate element, starting with the type and name of the attribute we want to animate in the parent circle shape:

<animate attributeType="xml" attributeName="fill-opacity" />

Now specify the values we want the animation to progress from and to:

<animate attributeType="xml" attributeName="fill-opacity" from="0" to="1" />

The shape will be invisible at the start of the animation and will be at full opacity at the end. Now specify when we want the animation to start, which will be as soon as the SVG loads in the page:

<animate attributeType="xml" attributeName="fill-opacity" from="0" to="1" begin="0s" />

To begin later specify a higher value. Now add the duration we want the animation to elapse over:

<animate attributeType="xml" attributeName="fill-opacity" from="0" to="1" begin="indefinite" dur="6s" />

Finally, add what we want to happen when the animation is complete – we will freeze the circle as it appears at the end of the animated effect:

<animate attributeType="xml" attributeName="fill-opacity" from="0" to="1" begin="indefinite" dur="6s" fill="freeze" />

Open your page in the browser – you should see the reflection fade in gradually.

Make a Shape Interactive

Let’s make the pupil shape (the black circle) interactive. We will make the stroke disappear when the user rolls their mouse over it, making the circle appear sharper. Then when the user rolls their mouse back off the shape, we will return the stroke to its original opacity. Start by adding the mouse over effect:

<circle cx="250" cy="200" r="70" fill="black" stroke="#121212" stroke-width="3px" stroke-opacity="0.5" onmouseover="this.setAttribute('stroke-opacity', 0);"/>

We use the standard onmouseover event listener attribute you may be accustomed to using with HTML elements – inside the attribute value is a short excerpt of JavaScript code. In the attribute code, we refer to the element using this, then call the setAttribute method to set a new value on the stroke-opacity attribute within the circle shape. Setting an opacity value of zero will make the stroke disappear when the user event occurs. Now add the effect for when the user rolls their mouse off the shape:

<circle cx="250" cy="200" r="70" fill="black" stroke="#121212" stroke-width="3px" stroke-opacity="0.5" onmouseover="this.setAttribute('stroke-opacity', 0);" onmouseout="this.setAttribute('stroke-opacity', 0.5);"/>

When this event occurs, we use the same method to return the stroke to the opacity it had originally. Open your page again and test the result by rolling your mouse on and off the black pupil circle:

svg-animation-interaction-mouse-over

As you can see, the effect is to make the shape seem sharper when the user has their mouse over it.

Animate on Interaction

Let’s combine the two effects now by animating an element on user interaction. Rather than starting the white reflection circle animation as soon as the page loads, let’s make it happen when the user clicks the iris circle. First alter the circle we already added the animate element to, initially setting the fill opacity to zero so that it is invisible when the page loads:

<circle cx="270" cy="180" r="20" fill="url(#lightGradient)" fill-opacity="0">

Now alter the animate element inside this shape to make the begin attribute indefinite, so that the animation does not start straight away:

<animate attributeType="xml" attributeName="fill-opacity" from="0" to="1" begin="indefinite" dur="6s" fill="freeze" />

Now add an event listener to the iris circle, like the ones we added to the pupil circle but for the onclick event this time:

<circle cx="250" cy="200" r="180" fill="url(#irisGradient)" stroke="#000033" stroke-width="3px" stroke-opacity="0.7" onclick="startAnim();"/>

When the user clicks the iris circle, the page will execute the function specified in the onclick attribute – this time we will store the code in a script section in the page head, so add it now:

<script type="text/javascript">
function startAnim(){
//animate
}
</script>

Inside the function, get a reference to the animate element and begin the animation:

function startAnim(){
document.getElementsByTagName('animate')[0].beginElement();
}

If you had more than one animate element in your SVG you would need to refine this code. We simply retrieve an array containing all of the animate elements in the page and, since there is only one, we use the first element in the array. The beginElement method starts the animation. Open your page and test this by clicking the iris circle. You should see the white reflection circle fade in as before, but not until you click.

As you can see, you can combine interaction and animation to create engaging effects for your users all within standard Web page markup code.

Conclusion

The interaction and animation we’ve explored in this tutorial may be basic, but you should begin to see how you can give your website users an interesting level of interaction. Try adding more effects to your pages – you may also wish to check out the animateTransform, animateColor and animateMotion elements for additional options. The W3C Animation specification is a great place to start.

About the author

I'm a developer and technical writer - see benormal.info for details. Follow me on Twitter @BrainDeadAir or email me at sue@benormal.info.

Share this post

Leave a Comment

Subscribe To Our Newsletter