Manipulating SVG Drawings
I first looked at using SVG in web sites about 5 or 6 years ago. At that time, a special browser plugin was needed to view an SVG and the javascript tools were not developed. I abandoned that first effort, even though the benefits of SVG were obvious. Flash to today: All of the current versions of the major browsers support SVG and the tools to manipulate the image are ready for general usage.
What is an SVG?
An SVG is a vector graphic that is described by its XML file. That means, for example, that each shape may be created or manipulated by simply modifying the XML descriptive text. I use the open source Inkscape software to create my base graphics.
About this Tutorial
The intent is to create a simple SVG with layers (groups in SVG) and then show or hide those layers dependent upon user actions on a web page. The demonstrated example may be viewed at bd-designs.com. All links in this post and all references used to develop the demonstration may be found via my delicious. Let’s get started.
The SVG Drawing
Create the drawing
- Import a scanned drawing into layer1 of a new Inkscape drawing
- Add a layer for the head
- Use the oval drawing tool to draw the head as a simple vector shape
- Add a layer for the body
- Use the Bezier curves tool to draw the body sides
- Use the oval tool to draw the body bottom
- Continue to add layers and vector shapes until the drawing with colors is complete
- Delete layer1, the layer with the scanned bitmap
- Save the file
Derive Layer Information from SVG
An SVG is a XML formatted text file. This means it may be viewed and edited in any basic text editor. For this demonstration, we are interested in only a few of the XML fields.
The <g>…</g> tag means group in SVG and is similar to the concept of layers when drawing. The id is the name of the group. Make a note of all of the groups and relate them to the layers you created in your drawing, shown by inkscape:label.
Set Scale and Viewbox
How your image appears in an HTML page is controlled by a number of settings, both in SVG and in HTML. For this demonstration, the whole SVG should appear in the page and its size will be set by HTML. Therefore in SVG set:
- viewBox=”0 0 width height”
- width=100%”
- height=”100%”
The width and height attributes already exist but you may have to add the viewBox attribute just after width and height.
The HTML Page
The intent of the page is to show how to draw a ballerina. The various steps are to be shown in an accordion menu. When each step is clicked, the drawing should show the layers associated with that step. When a user clicks back any number of steps, those subsequent layers should be hidden. This is done using the jQuery UI Accordion and svgweb.
Load the Libraries
In head place the following or similar code:
<script src="svgweb/src/svg.js" data-path="svgweb/src/"></script> <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
Set the On-Load Actions
In head place the following or similar code:
<script>
$(document).ready(function() {
// SET THE UI ACCORDION
// TO JQUERY UI
$("#accordion").accordion();
// ACCESS THE SVG ON LOAD
// TO SVGWEB
window.addEventListener('SVGLoad', function() {
var doc = document.getElementById('ballerina').contentDocument;
// GET THE SVG ELEMENT
var lay_head = doc.getElementById('layer2');
... other layers
// SET THE SVG ELEMENT'S ATTRIBUTE
var attr = 'display:none';
lay_head.setAttribute('style', attr);
... other attribute sets
}, false);
});
</script>
At this point, the document is ready to have its accordion menu fully implemented in HTML and the SVG may be displayed in its initial conditions. Some modifications to the above javascript will be needed later but lets move on to the HTML portion.
Accordion Container
The markup of your accordion container needs pairs of headers and content panels:
<div id="accordion">
<h3><a href="#"><b>Introduction</b></a></h3>
<div><p>Here you will learn how to draw a ballerina.</p></div>
<h3><a href="#"><b>Step 1: Head</b></a></h3>
<div><p>Draw a circle.</p></div>
... more accordion items
</div>
Image Object
If you are working with HTML 5, you may insert an SVG image directly but I find it more familiar to use the object tag. The object HTML must make exceptions for earlier versions of IE. The width and height set here are the actual display width and heights. If the viewBox was properly set earlier, the SVG will scale to fit the dimensions set here.
<!--[if !IE]>--> <object data="images/ballerina04.svg" type="image/svg+xml" id="ballerina" width="282" height="416"> <!--<![endif]--> <!--[if lt IE 9]> <object src="images/ballerina04.svg" classid="image/svg+xml" width="282" height="416" id="ballerina"> <![endif]--> <!--[if gte IE 9]> <object data="images/ballerina04.svg" type="image/svg+xml" width="282" height="416" id="ballerina"> <![endif]--> </object>
Toggle Layers
Once this point is reached, the document successfully displays the accordion menu and the SVG graphic in its initialized state. What is missing, is the ability to change the layers displayed depending on the accordion menu selected. More specifically, we need to act upon the change event of the accordion menu and that action depends upon which menu is active. Conveniently, the jQuery accordion menu provides just what we need.
// GET THE INDEX OF THE ACTIVE MENU OPTION var active = $( ".selector" ).accordion( "option", "active" );
and
// CALLBACK FUNCTION TO ACT ON THE CHANGE EVENT
$( ".selector" ).accordion({
change: function(event, ui) { ... }
});
Its time to put it all together and modify the previously created call to create the accordion menu:
// SET THE UI ACCORDION
// TO JQUERY UI
$("#accordion").accordion({
change: function(event, ui) {
var active = $('#accordion').accordion('option', 'active');
// active is a 0-based index to the active menu option
// MANIPULATE THE SVG
// GET SVG OBJECTS
var obj = document.getElementById('ballerina');
var doc = obj.contentDocument;
var lay_head = doc.getElementById('layer2');
var lay_body = doc.getElementById('layer3');
... other layers
// SET SVG ATTRIBUTES
var attr = 'display:inline';
switch(active){
case 1:
lay_head.setAttribute('style', attr);
break;
case 2:
lay_body.setAttribute('style', attr);
break;
... other cases
}
// SET SVG ATTRIBUTES = HIDE
var attr = 'display:none';
switch(active){
case 0:
lay_head.setAttribute('style', attr);
case 1:
lay_body.setAttribute('style', attr);
... other cases
}
}
});
Conclusion
The page is now complete with basic interactivity. Please do view the source of the example page, it has the full, working code for that menu and that image. I am certain you will think of many uses for layered SVG images and that is just a sample of what can be done using SVG and javascript.






