SVG Primer

SVG is the new in-thing in graphical presentation on HTML pages. Like HTML is to content display, SVG is to graphics display, in the same way as VRML is to 3D displays. So to get you started, a brief primer on SVG »»

Scalable Vector Graphics is a language for describing two-dimensional graphics in
XML. It is also described as an “XML application”.
What that
means to me is that it can be written simply using a text editor. And that
also means that it can be dynamically generated. That’s the whole reason for
excitement.

W3C also says – SVG allows for three types of graphic objects: vector
graphic shapes (e.g., paths consisting of straight lines and curves), images
and text. Graphical objects can be grouped, styled, transformed and composited
into previously rendered objects.
Additionally, SVG can be interactive,
i.e. take inputs; dynamic, i.e. animations can be achieved.

Note: As of now, SVG is supported only
as a plugin for Internet Explorer, Mozilla and Netscape. I would insist you
download the Adobe
SVG plugin
before you see the examples shown here. If you are using Mozilla,
they have an alternative SVG project going on at mozilla.org.
You can download the SVG enabled version of Mozilla from here.

In structure, SVG is similar to HTML. While HTML has tags like <body>,
<table>, <td>, etc., for drawing, SVG has tags like <polygon>,
<line>, <circle>. Instead of me going the traditional way of explaining
step-by-step lets start directly with an example. Take a look at the code
given below -

<rect
x = "10"
y = "20"
width = "100"
height = "100"
style = "fill:#0000FF; stroke:#666666; stroke-width:2;"
/>



As you can easily guess, this code draws a rectangle of equal width and height,
a square. It is not filled and has a line width of 2 pixels. The line colour
is grey. Also the x and y coordinates of the square have been mentioned. This
specifies the relative position of the square w.r.t. the SVG document.


That was pretty simple. Let’s take a look at the other shapes –


<circle 
cx = "50"
cy = "60"
r = "30"
fill = "yellow"
stroke = "blue"
stroke-width = "10"
/>


This will draw a circle of radius 30 pixels with its center at (50,60) relative
to the SVG document. It is filled with yellow and line is blue in colour.
Very simple again. Notice the difference in the style definition in the above
example and the earlier one. Both are valid definitions and you can choose
which one is suitable for you.


I think, we are pretty comfortable with basic shapes in SVG. In case, you
can have a look at the below examples for more basic shapes –


Ellipse:


<ellipse 
cx = "60" cy = "30" rx = "50" ry = "20"
fill = "green"
/>


This will create an ellipse with its center placed at (60,30) relative to
the SVG document. The longer radius is 50 pixels and shorter radius is 20
pixels.


Line:


<line 
x1 = "5" y1 = "5" x2 = "45" y2 = "45"
stroke = "#666666"
/>


This is a plain example of a line. You specify the start coordinates (5,5)
and the end coordinates (45,45) and the line style.


Polygon:


<polygon
points = "5,5 45,45 5,45 45,5"
stroke = "blue" fill = "none"
/>

Polygons are specified by all the corners which define the shape. Here, the
points are (5,5), (45,45), (5,45) and (45,5). Polygons can be convex or otherwise.
You need not specify the end points to be same as the start points. They are
automatically connected.


Path:


<path 
d = "M5,5 C5,45 45,45 45,5 Z"
stroke = "blue" fill = "none"
/>


Uh-Oh! This looks like a tough one. Here, M means moveto, C means
curveto and Z means closepath. Going by these definitions,
the path reads out as – move to coordinate (5,5). Then draw a smooth bezier
curve between the three points (5,45), (45,45) and (45,5). In the end, close
the path by connecting the end and the start points.


The path element is the most flexible of all elements. You can have
all sorts of curves, straight lines, polylines. In fact, using paths, you
can draw any of the basic shapes shown above. Other than the M, C and Z you
can have the following commands in paths –




Path Commands

Command Name Params Description
L (absolute)
l (relative)
lineto (x y)+ Draw a line from the current point to the given (x,y) coordinate which
becomes the new current point. L (uppercase) indicates that absolute coordinates
will follow; l (lowercase) indicates that relative coordinates will follow.
A number of coordinates pairs may be specified to draw a polyline. At
the end of the command, the new current point is set to the final set
of coordinates provided.
H (absolute)
h (relative)
horizontal lineto x+ Draws a horizontal line from the current point (cpx, cpy) to (x, cpy).
H (uppercase) indicates that absolute coordinates will follow; h (lowercase)
indicates that relative coordinates will follow. Multiple x values can
be provided (although usually this doesn’t make sense). At the end of
the command, the new current point becomes (x, cpy) for the final value
of x.
V (absolute)
v (relative)
vertical lineto y+ Draws a vertical line from the current point (cpx, cpy) to (cpx, y).
V (uppercase) indicates that absolute coordinates will follow; v (lowercase)
indicates that relative coordinates will follow. Multiple y values can
be provided (although usually this doesn’t make sense). At the end of
the command, the new current point becomes (cpx, y) for the final value
of y.
S (absolute)
s (relative)
shorthand / smooth curveto (x2 y2 x y)+ Draws a cubic Bézier curve from the current point to (x,y). The
first control point is assumed to be the reflection of the second control
point on the previous command relative to the current point. (If there
is no previous command or if the previous command was not an C, c, S or
s, assume the first control point is coincident with the current point.)
(x2,y2) is the second control point (i.e., the control point at the end
of the curve). S (uppercase) indicates that absolute coordinates will
follow; s (lowercase) indicates that relative coordinates will follow.
Multiple sets of coordinates may be specified to draw a polybézier.
At the end of the command, the new current point becomes the final (x,y)
coordinate pair used in the polybézier.

Although there are more commands which give you complete flexibility over
drawing paths, I think this would be enough for a novice’s needs. You can
have a detailed look at these commands at W3C’s
SVG site
.

Using them
Now that we know how to create shapes, how do we actually use them? You have
various options. Either you embed an SVG in an HTML document, or you display
it as a different page. To embed in an HTML paqe as an object -

<embed
src = "circles.svg"
width = "150" height = "150"
type = "image/svg+xml"

/>


See, it’s as easy as adding an image. You will notice the MIME type of an
SVG is "image/svg+xml" as opposed to "image/png" or "image/gif".
This is a glimpse of the future of XML documents where all images will be
treated as enbedded objects(XHTML 2.0).


circles.svg:


<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg">
<g style="fill-opacity:0.6;
stroke:black; stroke-width:2px;">
<circle cx="60" cy="30" r="20" style="fill:red;"/>
<circle cx="45" cy="55" r="20" style="fill:blue;"/>
<circle cx="75" cy="55" r="20" style="fill:green;"/>
</g>
</svg>

The above syntax should be followed for every SVG document. The <svg>
element is essential when using embedded SVG or standalone document. All graphic
elements lie inside the <svg> element. The structure indicates that
the <svg> and <circle> elements lie inside the XML SVG namespace.
They could be a part of an XML document or be separate as standalone SVG.

Another new thing that you see is the <g> element.
It is a container element for grouping together all related graphic elements
(such as <rect> , <circle>, <ellipse>, etc.). You can define
similar characteristics for elements in the same group. You can also have
nested groups.

That’s it! We are done with the primer. Wait, what about the animations?
Oh no, lets take it some other day. For now, take a peek at this
animated clock
(This one is written by Brandon Zylstra). Click on this
link to see the clock in motion. One caveat, this clock always starts from
all hands at 9 o’clock !!

SVG Clock:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg
width="500" height="500"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
zoomAndPan="magnify">

<desc>A Clock, my first SVG ever, hacked together by hand.
– Brandon Zylstra</desc>
<!— based on http://www.zvon.org/xxl/svgReference/
Standard/images/animate/animMotion01.svg ->


<!- Outline of clock,
with indicators for 12, 3, 6, and 9. —>
<path
d="M 100,250 C 100,50 400,50 400,250
C 400,450 100,450 100,250"
style="fill:none; stroke:black; stroke-width:7" />
<circle cx="100" cy="250" r="10" style="fill:black"/>
<circle cx="250" cy="100" r="10" style="fill:black"/>
<circle cx="400" cy="250" r="10" style="fill:black"/>
<circle cx="250" cy="400" r="10" style="fill:black"/>

<!— plot clockface center—>
<circle cx="250" cy="250" r="10" style="fill:black"/>

<!— Second hand ->
<path d="M 0,0 L -5,-5 L 0,-100 L 5,-5 L 0,0 z"
style="fill:black; stroke:white; stroke-width:1">
<!
- Define the motion path animation ->
<animateMotion dur="60s" repeatCount="indefinite"
path="M 200,250 C 200,182 300,182 300,250
C 300,318 200,318 200,250"
rotate="auto" />
</path>
<!
- Minute hand ->
<path d="M 0,0 L -5,-5 L 0,-100 L 5,-5 L 0,0 z"
style="fill:black; stroke:white; stroke-width:1" >
<!
- Define the motion path animation ->
<animateMotion dur="60m" repeatCount="indefinite"
path="M 200,250 C 200,182 300,182 300,250
C 300,318 200,318 200,250"
rotate="auto" />
</path>
<!
- Hour hand ->
<path d="M 0,0 L -5,-5 L 0,-100 L 5,-5 L 0,0 z"
style="fill:black; stroke:white; stroke-width:1" >
<!
- Define the motion path animation ->
<animateMotion dur="12h" repeatCount="indefinite"
path="M 200,250 C 200,182 300,182 300,250
C 300,318 200,318 200,250"
rotate="auto" />
</path>

<path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z"
style="fill:black; stroke:white; stroke-width:1"/>
<g id="guides" visibility="hidden">
<!- plot key points for clockface circle path—>
<circle cx="100" cy="50" r="5" style="fill:blue"/>
circle cx="400" cy="50" r="5" style="fill:blue"/>
<circle cx="400" cy="250" r="5" style="fill:blue"/>
<circle cx="400" cy="450" r="5" style="fill:blue"/>
<circle cx="100" cy="450" r="5" style="fill:blue"/>
<circle cx="100" cy="250" r="5" style="fill:blue"/>

<!— plot key points for hand path—>
<circle cx="200" cy="182" r="5" style="fill:purple"/>
<circle cx="300" cy="182" r="5" style="fill:purple"/>
<circle cx="300" cy="250" r="5" style="fill:red"/>
<circle cx="300" cy="318" r="5" style="fill:purple"/>
<circle cx="200" cy="318" r="5" style="fill:purple"/>
<circle cx="200" cy="250" r="5" style="fill:red"/> <!— example of second hand —>
<path d="M 10,0 L15,5 L 10,100 L 5,5 L 10,0 z"
style="fill:black; stroke:white; stroke-width:1" />
</g>

<!— Things this needs:

1) an easy way to specify the starting time, so that
the clock can start at an arbitrary time
2) the path for the hand is not perfectly circular.
I assume its done with Bezier curves, but I don’t
know the formula for those, so I figured out roughly
how it works and then basically eyeballed it until I
got it pretty darn close. Make the guides visible to
see where the key points are for calculating the
path, if you find they help you. I couldn’t have
done it without them.
—>
</svg


Resources:

6 Comments (closed)

Great primer! I thought it was about time I looked into SVG. It's a good start and I'll be applying this stuff soon. Thx!
Thanks, Jake for dropping by!
Hi Nilesh. Nice article and great looking site! I am the Jake that wrote the SVG Primer article and owner of codestore where the Pie Chart examples live ;o) Jake
Thanks boss!

Posted by
Sudhir

19 September 2002 @ 4 PM

Nilesh , This information was really fantastic, I am not writing just for the sake of formality, but it really is fantastic. Best part is simple, plain language which is compulsary for expalining any thing. Even I will try out some examples.If possible I will put some animation into my home page also. Continue such good work dost. Sudhir
Very useful stuff. Care to post on some tools for us creative types who don't mind, but would rather not code?