SVG Maker Project - Santa Drawing

This project is focused on the script that can be applied to many SVG images. The examples at the bottom of this page are taken from openclipart.org

The script uses the SVG styling property stroke-dasharray to draw the paths used to create the image. The stroke-dasharry property is used to draw dashed lines. It contains an array of numbers specifying the lengths of alternating dashes and gaps. The code below adds a stroke-dasharry property (just a 2 number array) to the style attribute of a path. Javascript continually increases the first number which simulates drawing the path.

Most image drawing tools use path commands to draw the shapes used in the image. This code works well for images that are comprised of path elements. After downloading the code of an SVG image from openclipart.org, copy the script below and paste it into the SVG image code, save the file and open it in a browser and watch how it was drawn. Simple.

A complete description of the code is provided, but the code can just be copied and used if it seems too complicated. Try to read the code and understand what is happening. Read the description below if it is not clear what is going on with the code. Sometimes it is easier to read the code than the description of it.

Javascript to draw paths

<script type="application/x-javascript"><![CDATA[
var DrawPaths = new function()
{
var l;
var increment;
var len;
var idx=0;
var paths;
var node;
var style;

window.addEventListener("load", init);

function init()
{
paths = document.getElementsByTagName("path");
for(var i=0;i<paths.length;i++)
{
style = paths[i].getAttribute("style");
paths[i].setAttribute("style","display:none;"+style);
}
getPath();
}

function getPath()
{
if(idx>paths.length) return;

node = paths[idx];
style = node.getAttribute("style");
len = node.getTotalLength();

increment=len/100;
if(increment<10) increment = 10;
l = increment;

setTimeout(drawPath,500);
}

function drawPath()
{
node.setAttribute("style","fill:none;stroke:magenta;stroke-width:1px;stroke-dasharray:"+l+","+len);
l+=increment;
if(l<len) setTimeout(drawPath,75);
else
{
style = style.replace("display:none;","");
node.setAttribute("style",style);
idx++;
setTimeout(getPath,50);
}
}
}();

]]>
</script>

Code Description

The code is contained in a container function DrawPaths() which keeps the variables used in local scope so not to conflict with any global variables - a good practice. The code first declares several variables (l, increment, len, idx, paths, node, and style) that will be needed. Then adds an event listener to call the init() function when the image is loaded.

The init() function loads the paths variable with a list of all elements with a tag name of "path" by calling the Document Object Model function getElementsByTagName(), which returns an array of all elements in the document with the tagname passed to the function. Next a "for loop" will loop through all of the elements in the array using a variable "i" that is incremented each pass through the loop. It loops while the variable i is less than the number of elements in the array (paths.length). Note the array is zero relative, so paths.length-1 is the last element in the array. With each pass through the "for loop", the code gets the style attribute for the indexed path (paths[i]), then sets the attribute to "display:none;" plus the style it previously contained. This hides all the path elements in the image. Once that is complete, the getPath() function is called.

The getPath() function will be called for all the path elements, so the first thing the function checks is if the idx variable is greater than the number of <path> elements (paths.length). If so, it returns because all the paths have been drawn. Since idx is initialized to 0, the code does not return assuming there is at least one <path> element in the document. Next the node variable is set to the paths array element indexed by the variable idx. The node variable now contains a path element in the document. Then the style variable is set to the style attribute of the element referenced by the node variable, saving it for later use.

Since the node variable is set to a <path> element, an SVG function can be called to get the total length of the path. The "len" variable is set to the value returned by calling the getTotalLength() function of the element referenced by the node variable.

The code is going to be changing the first digit in the stroke-dasharray property by incrementing it a fixed amount as the path is drawn, so the code next sets the variables need to do that. The "increment" variable will contain the fixed incremental amount the code will increase the stroke-dasharray of the path. It is set to the total length of the path (len variable) divided by 100. This is needed for long paths or it takes too long to draw. If the increment was set to something less than 10, the increment is set to 10. This is needed for short paths or they would take too long to draw. Then the "l" variable is intialized to the increment. The "l" variable will be used as the first number in the stroke-dasharry property. Lastly, the getPath() function sets a timer to call the drawPath() function after 500 milliseconds.

The drawPath() function will continually set the stroke-dasharry property while the first number of the property is less than the total length of the path. First the function sets the style attribute - note that the getPath() function has saved the style attribute so the code can restore it after the path is drawn. The style attribute is set to have no fill, a magenta stroke, and a stroke-width of 1 pixel. Note that some SVG images may contain a large viewBox and require setting the stroke-width to a larger value so it can be seen. The style also sets the stroke-dasharray to the variable "l" and the variable "len". The stroke will then be a dash the length determined by the variable "l" followed by a gap of length determined by the variable "len". Together they are longer than the path length, so only the initial dash will be seen.

Next the drawPath() function increases the variable "l", by the variable "increment" so the dash will be longer next time the function is called. The code then checks to see if the "l" variable is less than the "len" variable. If so, the path is not completely visible yet, so the code sets a timer to call itself, the drawPath() function, in 75 milliseconds. If the "l" variable is not less than the "len" variable, the complete path is now visible and the code will restore the original style attribute. It does this by first removing the "display:none;" property that was set to hide the element when the image loaded. The code then uses the "node" variable to set the style attribute for the <path> element. The "idx" variable is incremented to reference the next path in the paths array and a timer is set to call the getPath() function after 50 milliseconds.

Examples drawing the paths in SVG images

Click on an image below to watch it draw. All images from openclipart.org

SVG Maker Projects - coding SVG images - at STEAMcoded.org

STEAMcoded.org STEAMcoded.org