Page 1 of 2
Adobe's new open source graphics library makes working with SVG in code easy as long as you know your way around. Let's see what it can do.
The Snap.svg library provides a set of easy to use wrappers and utilities for all of the things you can do by directly addressing the DOM in code. It is written by the author of the Raphael library and has similarities . It is open source and free to use and supported by Adobe.
The big difference is that Raphael works with older browsers but Snap.svg needs IE9, Chrome, Firefox and Opera to work. Snap.svg supports features not in Raphael such as masking, clipping and gradients.
So if you want top of the range SVG then you need to use Snap.svg.
The next question is why bother with SVG based graphics at all?
Isn't Canvas supposed to be the big new HTML5 graphics thing?
Canvas provides bitmapped graphics which is great when you want to work with fixed resolution generated graphics or when you want to work with photos or other bitmap formats. SVG on the other hand provides resolution independent object oriented graphics.
Object oriented vector graphics are a lot easier to use if you are interested in animation or chaining the graphic in any way. For example if you draw a circle using Canvas then any notion of the circle is lost as soon as the command if finished. All you are left with are a set of pixels somewhere in the Canvas that have been set to some color of other. You can't easily give a command for the circle to change it size or location - its just part of the complete set of pixels. With SVG on the other hand if you draw a circle it is added as an object to the DOM and you can access it again and change its properties. That is you can tell the circle you have just drawn to change its radius or location and it will. This is the reason that SVG graphics are more suitable for animation.
There is also the small matter or resolution independence. An SVG graphic is a program that draws shapes and colors them in. When you run the program it creates the shapes at the current resolution what ever that is.
The bitmap graphics of Canvas have their place and so do the vector objects of SVG.
So Snap looks like a good idea and it has fairly good documentation and some examples. The problem is that the documentation is just a list of objects and methods in no particular order and it doesn't give you might idea what they are used for. The examples are generally complex and designed to show off Snap.svg rather than show you how things work. The purpose of this article is to explain the concepts and organize some of the features on offer.
Your First Snap.svg Program
The examples in this article all use the un-minified version of the library in Netbeans. So copy the dist directory into your project - and in Netbeans you can simply drag and drop the folder or the file. You can simply load the library in the head using:
Making sure if necessary to change the path to the correct location.
The Snap object is created when the library loads and this is used for all sorts of utility methods and to create the Paper object that represents the drawing surface.
There are ways you can create a Paper object
- you can use it to wrap an existing SVG element
- you can get it to generate and inject a Paper object into the DOM.
The simplest thing to do, especially when you are trying things out is to use :
to create and append an SVG object to the DOM of the specified width and height. This is easy but you don't get much control over where the new object is added to the page. If you want to control this more easily simply add an SVG tag in the page with a suitable id (or any selector):
Alternatively you can get the SVG element by any means you like and pass it to Snap:
var paper = Snap(svgElement);
This simplest thing to do is just create a new paper object wrapping a new SVG element.
Once you have the paper object you can start to draw using its drawing methods. For example, to draw a circle sy x=100, y=200 with radius 50
paper.circle(100, 200, 50);
You can draw a range of elements in the same way:
draw a circle center cx,cy radius r
draw line from x1,y2 to x2,y2
draw path using a path string - e.g. "M10,20 l 10,10" move t 10,20 line to 10+10,20+10
draw a rectangle at x,y with width and height w,h. Optionally add rx,ry to specify corner radius
draw ellipse at x,y with axes rx, ry
- paper.polyline(array of points) and
paper.polygon(array of points)
polyline - draw lines between all points/polygon - also create interior
draw text at x,y
draw a bitmap using the src URL at x,y with width and height
Each function returns an element of the appropriate type that you can use to further customize the way it looks.
The most important thing to understand about Snap.svg and SVG is that it is object oriented. When you use
paper.circle(100, 200, 50);
the circle appears on the screen but a circle object is also added to the DOM. With access to this DOM object you can change the circle at any time you care to by setting its attributes to some alternative values.
As already mentioned all of the drawing methods return element objects which wrap the DOM SVG object.
So for example:
var circ=paper.circle(100, 100, 50);
In this case we have stored a reference to the circle in circ and then used an object of attribute name/value pairs to set a red fill and a blue outline width 10. The colors are defined in hex using RGB format. Snap has some nice color utilities that make it easier to set the color.
As well as the attributes that you can set when you create the element e.g. x,y, r and so on you can generally also set fill, stroke and strokeWidth and a lot of others that you can lookup in the SVG documentation.
The most important idea is that as long as you keep a reference to the objects you create, circ for example, you can change their attributes at any time.
You can also group graphics elements together so that they work like a single big graphics element. For example:
var paper = Snap(svgElement);
var circ1 = paper.circle(100, 100, 50);
var circ2 = paper.circle(200, 150, 100);
group1 = paper.group(circ2, circ1);
In this case we have two overlapping circles that are grouped together. Now we can apply a set of attributes to all of the graphics elements in the group:
Which object in the group is "on top" depends on the order that you specify them in the call to the group method. The first elements are drawn first and so appear to be underneath the later elements.
Although a group behaves like on big graphics element you can stil access the different elements that make it up as long as you keep references to them.