Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Add interactivity to your SVG

Create SVG documents that respond to user input

Brian Venn (vennb@uk.ibm.com), Software Tester, IBM Business Integration, Hursley Park
Photo of Brian John Venn
Brian Venn joined IBM in October 2000, following three years at British Aerospace Defence Systems. He graduated from Southampton University with a degree in Astrophysics, and is certified in DB2 and software testing. He is is currently working in Integration testing at Hursley Park (UK).

Summary:  Scalable Vector Graphics (SVG) is an XML-based language for drawing two-dimensional graphics. However, its capabilities are not restricted to simple static vector shapes. This article shows how you can add interactive elements to your SVG documents that respond to user input.

Date:  27 Aug 2003
Level:  Introductory

Activity:  51868 views
Comments:  

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.

Linking

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.


Events

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.

Keypresses

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.


Scripting

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:

  1. 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 type attribute. Here it is set to text/javascript.
  2. <![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.
  3. Now you are ready to begin the script. First, three variables are defined: redVal, greenVal, and blueVal. These variables hold the red, green, and blue values, respectively, that you will use in your function. This function is called changeCol and takes in the parameter (evt). evt is a reserved SVG word that describes the event that has just happened. Here, the evt method is called getTarget(); this method returns a reference to the SVG object that triggers the event. This reference is then stored in the variable targetShape.
  4. Three random numbers with values between 0 and 255 are generated by a simple JavaScript Math function.
  5. Finally, the setAttribute method is called on targetshape. The object's fill attribute is set to an RGB value (such as rgb(150,200,50)) using the three random numbers generated in the previous step.
  6. After you close off the CDATA block and script, you return to SVG. A circle is drawn, and through the onClick element, it calls the function changeCol(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.

Interactive text

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:

  1. Assign an id to each text element that you refer to, so your script can retrieve them.
  2. 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.
  3. Call the evt methods getClientX() and getClientY() to get the X and Y coordinates of the pointer, and store them in the variables XPos and YPos.
  4. Create a new text node by calling svgDocument.createTextNode(). Pass the updated text string into this function.
  5. Finally, call the replaceChild method on the text element. This takes in two parameters -- the replacement text node and the child element that it's replacing. The call to getFirstChild() 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.


Summary

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.



Download

NameSizeDownload method
x-svgint.zip8KB HTTP

Information about download methods


Resources

About the author

Photo of Brian John Venn

Brian Venn joined IBM in October 2000, following three years at British Aerospace Defence Systems. He graduated from Southampton University with a degree in Astrophysics, and is certified in DB2 and software testing. He is is currently working in Integration testing at Hursley Park (UK).

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Web development
ArticleID=11832
ArticleTitle=Add interactivity to your SVG
publish-date=08272003
author1-email=vennb@uk.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers