10. Interaction

10.1 Interaction and the DOM

SVG provides support for interacting with an SVG document using the facilities in the W3C Document Object Model 2.0 (DOM) Recommendation. The DOM provides a standard way of accessing the attributes and properties defined in an SVG document and changing them via a scripting language. For example:

<svg  viewbox= "0 0 600 400" >
<script  type="text/ecmascript"><
function changerect(evt)
{
var svgobj=evt.target;
svgstyle = svgobj.getStyle();
svgstyle.setProperty ('opacity', 0.3, '');
svgobj.setAttribute ('x', 300);
}

</script>
<rect onclick="changerect(evt)" style="fill:blue;opacity:1" x="10" y="30" width="100" height="100" />
</svg>

This defines a diagram consisting of a single opaque blue rectangle close to the left hand edge. When the mouse or pointing device is clicked over it, the rectangle is repositioned further to the right and becomes semi-transparent.

As scripting languages vary in their capabilities and browsers vary in their support of them, the user may need some trial and error to get started. A general point is that the SVG script element behaves in much the same way as the one in HTML. In consequence, following the style used for HTML scripting will usually work for SVG as well.

In the example, the onclick attribute calls the script function changerect when the mouse click occurs. The variable evt passed as parameter to the changerect function enables the object over which the mouse was clicked to be identified. The property target of evt gives a reference to the object clicked. The variable svgobj is set to the object that was clicked. The ECMAScript method getStyle gives a reference to the object's style attribute, setProperty sets the value of a style property. The method setAttribute sets an attribute value.

The third parameter to setProperty will not be described. Assume you can always write it as an empty string.

Some of the events that can be handled by SVG are:

  • onclick
  • onactivate
  • onmousedown
  • onmouseover
  • onmousemove
  • onmouseout
  • onload

The event onactivate is more general than onclick and will work with devices other than mouse-like devices. The onload event gives a general method of invoking a script when an SVG document is loaded. For example:

<svg  viewbox= "0 0 600 400"  onload="changerect(evt)">
<script  type="text/ecmascript">
function changerect(evt)
{
var svgdoc = evt.getCurrentNode().getOwnerDocument();
svgobj = svgdoc.getElementByID ('MyRect')
svgstyle = svgobj.getStyle();
svgstyle.setProperty ('opacity', 0.3, '');
svgobj.setAttribute ('x', 300);
}

</script>
<rect id="MyRect"  style="fill:blue;opacity:1" x="10" y="30" width="100" height="100" />
</svg>

In this example, the variable svgdoc is set to point to the SVG document as a whole and svgobj is set to the rect object with id equal to MyRect. In this case, the rectangle will appear semi-transparent and on the right as soon as the SVG document is loaded.

It can be seen from these examples that the starting point for any interaction with an SVG document is obtaining a reference to the object tree (at an appropriate node) that represents the document. There are several ways to do this and different browsers may support different approaches. In designing an interactive SVG application, it is wise to start by thinking carefully about where modification will be required, and design the SVG document to facilitate this (for example, by including id attributes on appropriate elements).

10.2 Interaction Methods

The most useful methods for modifying an SVG document are:

  • getElementById
  • getStyle
  • setProperty
  • setAttribute
  • getAttribute
  • cloneNode

To create new elements, a useful method is cloneNode. For example:

<svg  viewbox= "0 0 600 400" >

<script type="text/ecmascript"><
function addrect(evt)
{
var svgobj=evt.target;
var svgdoc = svgobj.getOwnerDocument();
var newnode = svgobj.cloneNode(false);
svgstyle = newnode.getStyle();
var colors = new Array('red', 'blue', 'yellow', 'cyan', 'green', 'lime', 'magenta', 'brown', 
    'azure', 'burlywood', 'blueviolet', 'crimson');
var x = 10+480*Math.random();
var y = 10+330*Math.random();
var width = 10+100*Math.random();
var height = 10+50*Math.random();
var fill = Math.floor(colors.length*Math.random());
if (fill == colors.length) fill = colors.length-1;
fill = colors[fill];
svgstyle.setProperty ('opacity', 0.3+0.7*Math.random(), '');
svgstyle.setProperty ('fill', fill, '');
newnode.setAttribute ('x', x);
newnode.setAttribute ('y', y);
newnode.setAttribute ('width', width);
newnode.setAttribute ('height', height);
var contents = svgdoc.getElementById ('contents');
newnode = contents.appendChild (newnode);
}
</script>
<rect x="1" y="1" style="fill:#bbffbb"  width="598" height="398"/>
<g id="contents">
<rect onclick="addrect(evt)" style="fill:blue;opacity:1" x="250" y="100" width="20" height="20" />
</g>
</svg>

Hitting the single blue square rectangle in the middle of the diagram causes the function addrect to be invoked. This sets svgobj to point at the rectangle and svgdoc to point at the SVG document as a whole. The variable newnode is a new rectangle object (initially a copy of the element hit) that has its fill colour, position, size and opacity defined by resetting the attrributes and properties. The enclosing group with id set to contents has this new element appended to it as a new child. So after the first click on the blue rectangle the diagram will consist of two rectangles where the second has its position, size and properties randomly defined. After many clicks, the diagram might be as shown in Figure 10.1. This example illustrates a general style, namely creating new elements within an SVG document and then incorporating them into the SVG structure at the appropriate places.

No SVG Support

Figure 10.1: Cloning Rectangles