Interactivity in SVG can be separated into three areas -- linking, events, and scripting. This article looks at each one in turn.
Note: To view SVG documents in this tip, you need an SVG viewer which can be found (along with a .zip file that includes all associated files) in Resources.
The most basic form of interactivity is linking. In SVG this is provided in a fashion that's almost identical to that of an HTML link, through an <a> tag. Use it along with an xlink:href attribute to establish a link. Everything contained within the <a> and </a> tags is included as part of the link. Listing 1 shows an example of this, with three elements set to link to three different URL's. Click to see this in the browser.
The text, rectangle, and polygon elements all provide links to different pages, and show that any SVG element -- be it text, a circle, or a weird polygon -- can act as a link. If you move your mouse over these elements, notice that the pointer changes accordingly, indicating this is a link.
The functionality is pretty much identical to that of an image map (or hotspot) in HTML. However, in HMTL this can be a somewhat awkward process, involving manually drawing your hotspots over an image using a piece of dedicated software -- and if the image or links change, it can be a real pain to update them. In SVG, it is far simpler to define and maintain the links, mainly because the links can move dynamically with the SVG content.
Listing 1. Linking
<svg>
<a xlink:href="http://www.w3.org//Graphics//SVG//Overview.htm8">
<rect x="10" y="10" width="100" height="30" rx="10" ry="10"
style="fill:lightgrey"/>
<text x="30" y="30" font-size="12">Click here</text>
</a>
<a xlink:href="http://www-106.ibm.com//developerworks/">
<circle cx="100" cy="100" r="50" style="fill:grey"/>
<text x="80" y="100" font-size="12">Or here</text>
</a>
<a xlink:href="http://www.ibm.com/" target="new">
<polygon
points="60 160,165 172,180 60,290 290,272 280,172 285,250 255"
style="fill:dimgrey"/>
<text x="160" y="200" font-size="12">Or even here</text>
</a>
</svg>
|
Note the use of the target=new attribute in the polygon's xlink. This instructs the viewer to open up a new browser window when it is clicked.
SVG supports user events from the mouse such as click, mouseover, and mousedown. Listing 2 shows an example:
Listing 2. Interaction using the mouse
<svg>
<rect x="10" y="10" width="140" height="140" rx="5" ry="5"
style="fill:lightgrey">
<set attributeName="fill" from="lightgrey" to="red"
begin="mouseover" end="mouseout"/>
</rect>
<text x="200" y="75" font-size="30">Move over me and click
<set attributeName="font-size" from="30" to="35"
begin="mouseover" end="mouseout"/>
<set attributeName="fill" from="black" to="red"
begin="mousedown" end="mouseup"/>
</text>
</svg> |
Click to view this. The rectangle and text elements react to the different events, such as moving the mouse and clicking, to create a simple rollover effect. Try moving the mouse over the elements to see these effects. Any SVG property that can be applied to an element -- such as fill color, stroke-width, size, and opacity -- can be changed in this fashion.
The text element has two events that it reacts to -- mouseover and mousedown. This demonstrates that multiple events can be assigned to the same element. SVG supports many different events -- see Resources for a full list of all the event types at the W3C's SVG site.
When you want an event on one element to cause an action to occur on another element, assign id attributes to SVG elements and reference them. Listing 3 shows an example.
Listing 3 : Changing another element's properties
<svg>
<rect id="changeToRed" x="20" y="20" width="25" height="25" rx="5"
ry="5" style="fill:lightgrey"/>
<text x="50" y="35" font-size="14">Move over for red text</text>
<rect id="bigText" x="20" y="60" width="25" height="25" rx="5"
ry="5" style="fill:lightgrey"/>
<text x="50" y="75" font-size="14">Move over for big text</text>
<rect id="bigRedText" x="20" y="100" width="25" height="25" rx="5"
ry="5" style="fill:lightgrey"/>
<text x="50" y="115" font-size="14">Click me for big red text</text>
<text id="changingText" x="250" y="100" font-size="30"
fill="black">Change me
<set attributeName="fill" from="black" to="red"
begin="changeToRed.mouseover" end="changeToRed.mouseout"/>
<set attributeName="font-size" from="14" to="50"
begin="bigText.mouseover" end="bigText.mouseout"/>
<set attributeName="font-size" from="14" to="50"
begin="bigRedText.click" end="bigRedText.mouseout"/>
<set attributeName="fill" from="black" to="red"
begin="bigRedText.click" end="bigRedText.mouseout"/>
</text>
</svg>
|
Click to see this in your browser. The changes are made to the text when the mouse moves over the various rectangles. The three rectangles are assigned their respective id attributes, and the text's set element references these through "id.eventName". When the rectangle's events are triggered, the text's attributes change accordingly.
You can also fire off an animation in response to an event. Listing 4 shows an example of this:
Listing 4. Starting an animation
<svg>
<rect x="20" y="20" width="250" height="250" rx="5" ry="5"
style="fill:red">
<animate attributeName="opacity" from="1" to="0"
begin="click + 1s" dur="1s" fill="restore" />
</rect>
<circle cx="250" cy="250" r="100" style="fill:blue">
<animate attributeName="fill" from="blue" to="green"
begin="mouseover" dur="2s" fill="restore" />
</circle>
</svg>
|
Click to view this. When you click the rectangle, it fades out, and moving the mouse over the circle causes its color to change. Note that you can delay the start of the animation by using a "+Xs" in the begin attribute.
While most interaction with SVG is through the mouse, SVG also supports keyboard input. This is achieved using the accessKey event handler, as shown in Listing 5.
Listing 5. Capturing a keypress
<svg>
<rect x="20" y="20" width="100" height="100" rx="5" ry="5"
style="fill:red">
<animate attributeName="opacity" from="1" to="0"
begin="accessKey(1)" dur="3s" fill="restore" />
</rect>
<rect x="140" y="20" width="100" height="100" rx="5" ry="5"
style="fill:red">
<animateTransform attributeName="transform" type="rotate"
from="0" to="90" begin="accessKey(2)" dur="3s"/>
</rect>
<rect x="260" y="20" width="100" height="100" rx="5" ry="5"
style="fill:red">
<animateColor attributeName="fill" from="red" to="green"
begin="accessKey(3)" dur="3s" />
<animate attributeName="y" from="20" to="100"
begin="accessKey(
)" dur="3s" fill="restore" />
</rect>
</svg>
|
Click to view this. The three rectangles are set to respond to number keys 1, 2, and 3 on your keyboard. Try pressing each of them to see images react accordingly.
You can set an element to respond to any number of different keys. Note that the third rectangle is set to listen for two keypresses. The second accessKey handler on the third rectangle, is set to listen for the key (
) -- you may recognise this as the standard HTML encoding for the carrage return (Enter) key. To specify any special or whitespace characters, you must use the HTML encoding format of &#XX, where XX is the ASCII character code.
So far I've covered just the basic ways to respond to events using the built-in functions supported by SVG. While you can achieve a lot using just these alone, you need to turn to scripting to achieve more advanced effects. SVG supports scripting languages such as VBScript and JavaScript; for these examples, I'll use JavaScript.
For an SVG object to respond to a scripted event, the prefix on is added to the trigger names, so click becomes onclick, mouseover becomes onmouseover, and so forth. Listing 6 shows an example of an SVG script.
Listing 6. Scripting SVG using JavaScript
<svg>
<script type="text/javascript">
<![CDATA[
var redVal=0;
var greenVal=0;
var blueVal=0;
function changeCol(evt)
{
var targetshape = evt.getTarget();
redVal = Math.round(Math.random()*255);
greenVal = Math.round(Math.random()*255);
blueVal = Math.round(Math.random()*255);
targetshape.setAttribute("fill",
"rgb(" + redVal + "," + greenVal + "," + blueVal + ")");
}
// ]]>
</script>
<circle cx="200" cy="200" r="100" fill="blue"
onclick="changeCol(evt)" />
</svg>
|
Look at Listing 6 step by step:
- The first step when scripting SVG is to inform the viewer that you are no longer working with SVG but are now working in a scripting language. You must also define which scripting language you are coding in with the
typeattribute. Here it is set totext/javascript. <![CDATA[is the XML command that tells the viewer to stop parsing the code and read the code within the block that follows as character data. This prevents the viewer from processing brackets and other special characters as SVG elements, and makes it easier for you to write your scripts.- Now you are ready to begin the script. First, three variables are defined:
redVal,greenVal, andblueVal. These variables hold the red, green, and blue values, respectively, that you will use in your function. This function is calledchangeColand takes in the parameter(evt).evtis a reserved SVG word that describes the event that has just happened. Here, theevtmethod is calledgetTarget(); this method returns a reference to the SVG object that triggers the event. This reference is then stored in the variabletargetShape. - Three random numbers with values between 0 and 255 are generated by a simple JavaScript
Mathfunction. - Finally, the
setAttributemethod is called ontargetshape. The object'sfillattribute is set to an RGB value (such asrgb(150,200,50)) using the three random numbers generated in the previous step. - After you close off the
CDATAblock and script, you return to SVG. A circle is drawn, and through theonClickelement, it calls the functionchangeCol(evt)when clicked.
Click to view this. When you click on the circle, its fill changes to a random colour on each click.
Scripting is most useful when the same function is applied to multiple SVG elements. For example, you could add a rectangle to Listing 6 as follows:
<rect x="400" cy="400" width="100" height="100" fill="blue"
onclick="changeCol(evt)" />
|
When clicked, the rectangle changes its color by calling the same script as the circle did.
To see this, take a look at this other example. If you examine the source code, you see three methods, changeCol, changeEdge, and resetEdge. Try moving the mouse over the rectangle and clicking around it. All the rectangles are set to respond to onclick, onmouseover, and onmouseout events, and all call the same scripted functions to do this. Also note the onload attribute: This is called when the SVG document is first loaded and is useful for performing initialisation on your SVG.
Creating interactive text in SVG is somewhat trickier than you might think. When a text element is defined, the displayed text is a child of the text element, and not an attribute like font-size, hence you can't simply use a setAttribute call to modify its content like you've been doing so far. Instead you must create a new text element, and use it to replace the current one. Listing 7 shows an example.
Listing 7. Scripting text changes
<svg>
<script type="text/javascript">
<![CDATA[
function changeText(evt)
{
targetXtext=svgDocument.getElementById("XPos");
targetYtext=svgDocument.getElementById("YPos");
var XPos = evt.getClientX();
var YPos = evt.getClientY();
var newXPosText = svgDocument.createTextNode("X Position : " + XPos);
var newYPosText = svgDocument.createTextNode("Y Position : " + YPos);
targetXtext.replaceChild(newXPosText,targetXtext.getFirstChild());
targetYtext.replaceChild(newYPosText,targetYtext.getFirstChild());
}
function changeTextNotOver(evt)
{
targetXtext=svgDocument.getElementById("XPos");
targetYtext=svgDocument.getElementById("YPos");
var newXPosText =
svgDocument.createTextNode("X Position : Not over Rectangle");
var newYPosText =
svgDocument.createTextNode("Y Position : Not over Rectangle");
targetXtext.replaceChild(newXPosText,targetXtext.getFirstChild());
targetYtext.replaceChild(newYPosText,targetYtext.getFirstChild());
}
function recordClick(evt)
{
targetClickText=svgDocument.getElementById("ClickPos");
var XPos = evt.getClientX();
var YPos = evt.getClientY();
var newClickText =
svgDocument.createTextNode("Last Click made at X=" + XPos + " Y=" + YPos);
targetClickText.replaceChild(newClickText,
targetClickText.getFirstChild());
}
// ]]>
</script>
<text id="XPos" x="50" y="50"<X Position :</text>
<text id="YPos" x="50" y="70"<Y Position :</text>
<text id="ClickPos" x="50" y="90"<Last Click made at : </text>
<rect x="50" y="100" width="200" height="200" style="fill:blue"
onmousemove="changeText(evt)" onmouseout="changeTextNotOver(evt)"
onclick="recordClick(evt)"/>
</svg>
|
Click to view this. When you move the mouse over the rectangle, the X and Y positions of the mouse are shown and change as the mouse moves; clicking the mouse on the rectangle records the position of the click.
Looking at the function changeText(evt) shows the steps to create interactive text:
- Assign an
idto each text element that you refer to, so your script can retrieve them. - Make an initial call to
svgDocument.getElementById(), where the parameter passed in is the ID of the text element that will be changed. This is stored in a variable for later use. - Call the
evtmethodsgetClientX()andgetClientY()to get the X and Y coordinates of the pointer, and store them in the variablesXPosandYPos. - Create a new text node by calling
svgDocument.createTextNode(). Pass the updated text string into this function. - Finally, call the
replaceChildmethod on the text element. This takes in two parameters -- the replacement text node and the child element that it's replacing. The call togetFirstChild()ensures that the updated text is placed correctly.
By using Listing 7 as a reference, you should be able to incorporate interactive text into your own SVG documents.
You can use any of the of interactivity techniques described in this article to make your SVG documents more useful to your users. Try experimenting with combinations of these to get the functionality that you want.
Take a look at this little sample to see how you could combine these techniques to make an interactive menu.
| Name | Size | Download method |
|---|---|---|
| x-svgint.zip | 8KB | HTTP |
Information about download methods
- Download all of the sample files in this article.
- Read the Scalable Vector Graphics (SVG) 1.0 Specification or the latest 1.2 Specification.
- Read the complete list of supported events at the W3C site.
- Try Adobe's SVG Zone for many SVG resources, including an area where you can download an SVG viewer.
- Check out Brian Venn's developerWorks article "Bringing Scalable Vector Graphics to life", an introduction to creating animation in your SVG documents (June 2003).
- Take Nicholas Chase's developerWorks tutorial "Introduction to SVG", a good starting point to learn SVG (February 2002).
- Take interactivity to the next level with Andrew Watts' developerWorks tutorial "Interactive, dynamic Scalable Vector Graphics" (June 2003).
- Find more XML resources on the developerWorks XML zone.
- IBM's DB2 database provides not only relational database storage, but also XML-related tools such as the DB2 XML Extender which provides a bridge between XML and relational systems. Visit the DB2 Developer Domain to learn more about DB2.
- Find out how you can become an IBM Certified Developer in XML and related technologies.




