The Important Bits of SVG

Introduction

Scalable Vector Graphics (SVG) is an XML standard, like HTML, where two-dimensional pictures are described with tags. This page isn't meant to be a comprehensive guide. Check the W3C Spec for the full power of SVG. This page will get you dangerous.

SVG is supported by most modern browsers. You can enter it directly into my PHP echo page, a text document on your computer (and then open it with Chrome / Firefox / IE 8+), or run it through a rasterizer (like Batik) to turn your SVG XML into a JPEG or PNG for easier sharing or offline publishing. If you're trying to get really fancy, an XML document that's supported by a web browser is a total target for JavaScript DOM manipulation. This is cool for procedural image generation, like fractal art or generating charts or graphs.

Tag-based picture generation starts with an svg tag that describe what the actual output looks like. Attributes describe the size of the picture and its background color and some other interesting bits. It's the parent of the rest of the image, which ultimately will contain colored shapes that represent something nice.

<svg width="300px" height="250px" viewBox="0 0 640 480">
<!-- Picture goodies -->
</svg>

The viewBox stuff is completely optional, but it's hugely handy. The syntax is space separated values for minimum x and y values, followed by the maximum x and y values for the coordinate system. We'll be defining all our shapes in terms of coordinates, and if you want to resize your image later (for print vs. online, or for multiple resolutions... part of the beauty of scalable vector graphics), then separating the local coordinate system from the actual image size is fantastically usefully.

Basic Shapes

Within the svg tag lives all the shapes. Basic shapes each get their own tags with attributes that describe how they're rendered.

Circles are generated with the circ tag. Attributes are cx, cy for the center (x, y) point. Size is specified by r for radius.

Rectangles are generated with the rect tag. Attributes are x, y, width, amd height for its (x, y) top-left point, width and height respectively. Negative width and height values will make the rectangle stretch up and left instead of down and right. Attributes rx and ry can be used to round the edges.

Ellipses are generated with the ellipse tag. Attributes are cx, cy for the center point, and rx and ry to specify the length of the x and y axes.

Lines are generated with the line tag. Attributes are simply x1, y1, x2, and y2 for the two coordinates represeting the end-points of the line segment.

Polygons and polylines are generated with polygon and polygon tags, respectively. Polygons are closed shapes where polylines are a convenient way of sticking a bunch of point tags together. They both take a single attribute for describing their shape: points which are a space-delimited list of coordinates. Here's an example:

<polygon points="0,0 0,50 50,50 50,0 0,0" />

Text gets its own tag, too: text. Attributes include x and y for positioning, and font-family and font-size. Text just sits inside the tags. As an added bonus, tspan attributes can be nested to change a subset of the text— useful for colors, which we'll talk about in a little bit.

<text x="10" y="10" font-family="impact">OH HAI</text>

True story: my work computer doesn't have image-editing software, but using HTML tags and SVG, the above code example has been used in conjunction with a screenshot tool to generate some memes.

Paths are special turtle-graphics constructs that get their own little metalanguage. It's a bit dense for the purpose of this tutorial. They're described here.

Transformations

In the introduction, I mentioned that SVG and be generated or modified by JavaScript. You can also do fun things like defining groups (g tag). So, generating a piece of geometry and then coookie-cutter-style graphics can be generated... but then translation, rotation, and skewing could be important. Indeed, allowing SVG to handle rotation makes just static image generation easier.

Each of the basic shapes allows loads of extra attributes beyond what was covered in the previous section. An important one being transform. This attribute is given a string that looks like a function call.

Translation is moving a shape or group across and down a coordinate system. The first coordinate is the x transformation, and the second, optional, argument is y.

<rect w="100" h="100" transform="translate(30, 30)" />

Similarly, there's scale, rotate, skewX and skewY. Scale can take one or two arguments for how scaling should work. Rotation takes a rotation value in clockwise degrees (and an optional x, y center-point). The skewing functions also take a degree value, but require some guess-and-check because they're a little less intuitive than the other fucntions.

A few paragraphs ago, I mentioned cookie-cutter style data-pasting... which would be useful for a particle system. The trick to this is to name a graphical element (a basic shape or group) with an id attribute, then use the use tag to create clones. This is difficult to explain, so here's a very primitive example:

<svg width="50" height="50">
<rect id="recty-the-rectangle" x="10" y="10" width="20" height="20" />
<use xlink:href="#recty-the-rectangle" transform="translate(20, 20)" fill="#00F" />
</svg>

Strokes and Colors

If you're checking out SVG, you're probably already familiar with HTML/CSS. If not, go off and learn how colors work in web world first— because it's exactly the same here.

Any of the basic shapes also get an attribute for color, stroke— controlled by stroke-width, stroke-linejoin (which can be miter, round, or bevel), and stroke-linecap (which can be round, butt, or square). color specifies a fill-color, and stroke specifies a stroke color. They can also be patterns and gradients.

As an example, some ways of specifying the color white are: #FFF, #FFFFFF, rgb(255,255,255), rgb(100%, 100%, 100%), or white.

Opacity (called "alpha" in some circles) is specified by fill-opacity and stroke-opacity. They get a float value where 0.0 is fully see-through and 1.0 is fully opaque.

Clipping

It's worth calling out that you can punch shapes out of other shapes. This is done by creating a group with the clipPath tag and giving it an id attribute. Then, you can use that id to clip out of your target group/shape by giving this target a clip-path attribute. I'm running out of time writing this before work, so here's an example:

<clipPath id="clippy">
<rect x="100" y="100" width="100" height="100" />
</clipPath>
<rect clip-path="url(#clippy)" x="50" y="50" width="100" height="100" fill="red"/>

That will make a square that's the intersection of clippy at the specified rect.

So, I hope something's been learned here. This page is a pretty handy reference. Now, you can go back home!