Showcase and discover digital art at yex

Follow Design Stacks

Subscribe to our free newsletter to get all our latest tutorials and articles delivered directly to your inbox!

Creating new elements

Creating new elements

Now it will be shown how to create new elements.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="300" height="300">
<script type="text/ecmascript"><![CDATA[
var svgNS = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";
function createRect() {
var newRect = document.createElementNS(svgNS,"rect");
newRect.setAttributeNS(null,"width",Math.random() * 100);
newRect.setAttributeNS(null,"height",Math.random() * 100);
newRect.setAttributeNS(null,"x",Math.random() * 250);

newRect.setAttributeNS(null,"y",Math.random() * 180 + 60);
newRect.setAttributeNS(null,"fill-opacity",Math.random());
var red = Math.round(Math.random() * 255);
var green = Math.round(Math.random() * 255);
var blue = Math.round(Math.random() * 255);
newRect.setAttributeNS(null,"fill",
"rgb("+ red +","+ green+","+blue+")");
document.getElementById("firstGroup").appendChild(newRect);
}
function createText() {
var newText = document.createElementNS(svgNS,"text");
newText.setAttributeNS(null,"x",Math.random() * 200 + 50);
newText.setAttributeNS(null,"y",Math.random() * 180 + 60);
newText.setAttributeNS(null,"font-size","13px");
newText.setAttributeNS(null,"text-anchor","middle");
newText.setAttributeNS(null,"fill-opacity",Math.random());
var red = Math.round(Math.random() * 255);
var green = Math.round(Math.random() * 255);
var blue = Math.round(Math.random() * 255);
newText.setAttributeNS(null,"fill",
"rgb("+ red +","+ green+","+blue+")");
var textNode = document.createTextNode("a new text");
newText.appendChild(textNode);
document.getElementById("firstGroup").appendChild(newText);
}
function createUseElement() {
var newUseEl = document.createElementNS(svgNS,"use");
newUseEl.setAttributeNS(null,"x",Math.random() * 200 + 50);
newUseEl.setAttributeNS(null,"y",Math.random() * 180 + 80);
newUseEl.setAttributeNS(xlinkNS,"href","#mySymbol");
newUseEl.setAttributeNS(null,"fill-opacity",Math.random());
document.getElementById("firstGroup").appendChild(newUseEl);
}
]]></script>
<defs>
<symbol id="mySymbol" overflow="visible">
<rect id="redRect" fill="red" stroke="none"
x="-10" y="-10" width="20" height="20" />
<use transform="rotate(45)" xlink:href="#redRect" />
</symbol>
</defs>

<g id="firstGroup">
<text x="20" y="30" onclick="createRect()" font-size=+13px">
Click on this text to create a new rectangle.</text>
<text x="20" y="45" onclick="createText()" font-size=+13px">
Click on this text to create a new text.</text>
<text x="20" y="60" onclick="createUseElement()" font-size=+13px">
Click on this text to create a new use element.</text>
</g>
</svg>

Link to example 6 (create_elements.svg) – in a separate window)

In order to create a new element the method ]document.createElementNS() is used. The arguments are: namespace (in this case it needs to be explicitly set to the correct namespace url, here it is defined in the variable svgNS) and element name. The element reference is defined in a new variable, in this example “newRect”. This reference is later used to set attribute values as described in the above code. Usually a range of attributes need to be defined. Finally, the newly created element needs to be appended to an existing group or element in the document tree. In this example the new rectangles are appended to the group with the id “firstGroup”. The created elements are therefore siblings of the text element and are appended after it.

Creating text elements is different: you have to create a create a text-node using the document.createTextNode("yourText") method, that is later appended to the text element that you dynamically created as well. See above function createText() for an example.

Creating <use /> elements is different as well. You have to explictly use the xlink namespace when setting the href attribute. See function createUseElement() listed above as an example.

It is obvious that creating elements like in the method above, requires a lot of javascript code. One alternative would be to write a generic javascript function or object where you pass the element name and all attribute/value pairs and the function would create the elements. This would reduce the number of lines in the javascript if you have to create lots of different elements.

Another alternative is to build strings containing the svg code of an element and use the method parseXML() to append it to a child. The code below illustrates how you would use that method for creating a new rectangle:

var newRect = ‘<rect x=”‘+Math.random()*250+”‘ y=”‘+Math.random()*200+60+'” width=”‘Math.random()*100′” height=”‘Math.random()*100′” fill=”red” stroke=”blue”/>’; document.getElementById(“firstGroup”).appendChild(parseXML(newRect,document));

I personally did not do any performance tests to find out which method is faster, but other people told me that the parseXML() method is faster when creating a lot of elements.

Comments