Did you know that modern browsers already implement builtin support to visualize SVG drawings? And that you can make changes on them from the HTML document and make changes into the document from the SVG? In this post I’m going to explain all that through a simple example.
To create the SVG document you can use Inkscape. This program has a nice feature that allows you to edit attributes of particular nodes. For instance, you can select such a node, open the XML editor (Edit –> XML Editor…) and add a new attribute onclick
to the node with the value:
javascript:window.parent.document.form1.bodypart.value='head';
When you’ve finished, just save the document as “plain SVG” to prevent compatibility problems.
Let’s go to the HTML part now. The easiest way to show the SVG in the document is by using an “embed” tag:
<html> <body> <h1>Anatomy of a smiley</h1> <form name="form1"> Body part: <input type="text" name="bodypart" /> <br/> </form> <embed id="smiley" src="smiley.svg" width="745" height="1053" /> </body> </html>
But that’s not enough. If you want to change SVG attributes using javascript, just add this code:
<script type="text/javascript"> function changeColor(color) { var path=document.getElementById("smiley") .getSVGDocument() .getElementById("path2383"); path.style.setProperty("fill",color, ""); } </script> [...] Color: <input type="text" name="color" value="#FFFF00" /> <br/> <input type="button" value="Change color" onclick="javascript:changeColor(this.form.color.value);"/> <br/>
And that’s all. Now you have bidirectional knowledge between your HTML document and your SVG document. Take a look here to see the whole example.
There are still pending issues, like embedding the SVG code as part of the HTML source. That can be done including the proper DTDs and making sure that the document is interpreted as XHTML (that’s the most important think). Here is a modified version of the previous example to illustrate that, but I hadn’t been able to resolve nodes using this kind of embedded drawings.
Very nice.
Much more SVG via http://svg.startpagina.nl
You can navigate the inline version as you would an xml. For example you just need to change the path in changeColor() to document.getElementById(“path2383”). You can also give the input elements their own id attribute; the onclick events can then get to the appropriate element with getElementByid.
Thank you very much for your hint, milo.
Thanks for the class, master. I was searching like a crazy about how to modify svg attributes form html. Really thanks.
Gracias por la clase, maestro. Estaba como loco buscando cómo modificar los atributos de un svg desde un html. Curioso cómo han de prepararse ambos archivos para que se entiendan.
Gracias de nuevo, Enrique “NeoChucky”.
Os dejo una versión modificada / I left to you a modified version.
HTML:
function changeColor(bodypart,color){
if (bodypart == “head”)
{
var Head=document.getElementById(“smiley”).getSVGDocument().getElementById(“head”);
Head.style.setProperty(“fill”,color, “”);
}
else if (bodypart == “lefteye”)
{
var LeftEye=document.getElementById(“smiley”).getSVGDocument().getElementById(“lefteye”);
LeftEye.style.setProperty(“fill”,color, “”);
}
else if (bodypart == “righteye”)
{
var RightEye=document.getElementById(“smiley”).getSVGDocument().getElementById(“righteye”);
RightEye.style.setProperty(“fill”,color, “”);
}
else if (bodypart == “smile”)
{
var Smile=document.getElementById(“smiley”).getSVGDocument().getElementById(“smile”);
Smile.style.setProperty(“stroke”,color, “”);
}
}
Anatomy of a smiley
Click on different parts of the smiley to make their name appear in the first
textbox (interaction from the SVG to the HTML). Type a color code in the second
textbox and press the button to change the smiley color (interaction between the
HTML and the SVG).
Click here to see the SVG and view its source code.
Body part:
Color:
SVG:
A greeting to all / Un saludo a todos.
Is there a method to change multiple paths in an SVG file with the same name at the same time? (path id=”namehere”)
I don’t really know. In principle, ids should be unique, so I don’t know what would happen if there are duplicate ids in the document.
What if I group all these paths? Is it possible to address the name of a group and change an attribute of all paths inside it with a “for” loop?
Yes, what you propose can be done. I’ve updated the example (see the source code) and added a new function and a new button to do just that:
function changeMultipleColor(color) {
var group=document.getElementById("smiley").getSVGDocument().getElementById("layer1");
var elements=group.getElementsByTagName("path");
for (var i=0; i<elements.length; i++) {
elements[i].style.setProperty("stroke", color, "");
}
}
In general, you can use all the DOM manipulation functions, such as getElementById(), getElementsByName(), getElementsByTagName(), getElementsByTagNames(), getElementsByClassName(), getElementsBySelector(), getElementsByAttribute() or getElementsByAnything().
Great, now that I know how, I noticed that Illustrator CS3 loses all the groups information when I save the vector graphic in SVG format. All the objects are ungrouped and saved on one layer.