Basic Objects

Circle, Ellipse, Line, Rect, Image, Text

(see exercises at end of section)

<circle>


Let's begin, once more, with the "simplest SVG document":
  1. <svg xmlns="http://www.w3.org/2000/svg">
  2.    <circle r="50"/>
  3. </svg>
simplest SVG file: a circle centered at 0,0
circle1.svg


Make sure you can open it in your browser and now let's experiment.

The r attribute of the circle controls its radius. By default, the circle is centered at (0,0). We may change its center by changing the values of cx and cy.

Let's expand the radius to 100 pixels and move the center to the point (200,150). While we're at it, let's make the circle red, by setting its fill attribute:

  1. <svg xmlns="http://www.w3.org/2000/svg">
  2.    <circle r="100" cx="200" cy="150" fill="red"/>
  3. </svg>
a red circle centered at 200,150
circle2.svg



line>

The <line> object draws a line between two specified points: (x1,y1) and (x2,y2). In order to see the line, it must have a stroke (i.e., a color).

The code <line x1="10" y1="10" x2="100" y2="100"> draws an invisible line in most browsers, while in ASV+Internet Explorer, a faint hint of a grey line might be seen (which, curiously, does not expand in size when we zoom in on it).

Hence, a sort of minimal line consists of code such as the following:

  1. <line x1="5" y1="5" stroke="red" x2="90" y2="90" />

Another attribute known as "stroke-width" controls the thickness of the line and, by default, is assigned a value of 1.

The stroke and stroke-width attributes as well as the starting and ending points are varied in the following illustration:
  1. <line x1="5" y1="10" x2="99" y2="30"
    stroke-width=".5" stroke="red"/>
  2. <line x1="5" y1="30" x2="99" y2="50"
    stroke-width="1" stroke="red"/>
  3. <line x1="5" y1="50" x2="99" y2="70"
    stroke-width="2.5" stroke="red"/>
  4. <line x1="5" y1="70" x2="99" y2="90"
    stroke-width="6" stroke="blue"/>
four lines varying stroke-width
line1.svg

A number of other attributes exist for lines, two of which: the stroke-dasharray and the stroke-linecapare worth mentioning in this treatment.
  1.  <line x1="15" y1="15" x2="140" y2="135" stroke-width="25"
     stroke="blue" stroke-linecap="round"/>
  2.  <line x1="15" y1="15" x2="140" y2="135" stroke-width="25"
     stroke="aqua" stroke-dasharray="8,3,2,18"/>
  3.  <line x1="15" y1="155" x2="160" y2="60" stroke-width="25"
     stroke="blue"/>
  4.  <line x1="15" y1="155" x2="160" y2="60" stroke-width="25"
     stroke="orange" stroke-dasharray="8,3,2"/>
lines varying stroke-dasharray and stroke-linecap
line2.svg

The stroke-dasharray gives a flexible way of making dashed lines, shape borders, and paths. In the above illustration, we have made two pairs each consisting of two identical lines (except for the stroke and its dasharray) one on top of the other. The top line of each pair has had its stroke-dasharrayapplied which takes a sequence of numeric values S=(v1,v2,v3,...,vn) and turns the stroke on and off: on for the first value v1 pixels along the length of the line; off for the next v2 pixels and so forth. If the sum of the values vi in S is less than the length of the line, then the values are repeated again as needed. In the case of the first line, the value of stroke-dasharray="8,3,2,18" has an even number of values so the blue and aqua colored bands repeat aqua 8 pixels, clear 3 pixels, aqua 2 pixels and clear 18 pixels, starting over again with 8 more pixels of aqua. Since the underlying but identically shaped line is blue, the blue of the underlying line is what shows. In the case of the second line, the value of stroke-dasharray="8,3,2" has an odd number of values so the repeating sequence goes like this:

(8 orange, 3 clear, 2 orange, 8 clear, 3 orange, 2 clear, ...).

The first of the two pairs of lines has two lines; both use stroke-linecap, having stroke-linecap="round". This makes the end of the line rounded instead of flat, as in the second example which uses the default or flat value of stroke-linecap.

Another useful aspect of lines involves the <marker> tag which can be used to define arrow or other shapes appropriate for attaching to the beginning or ends of lines. The W3C gives a clear example (http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#footnote7sym)  for those so interested, though it is a bit verbose for our treatment here. Another example can be seen at http://srufaculty.sru.edu/david.dailey/svg/newstuff/simpleshapes.svg (http://srufaculty.sru.edu/david.dailey/svg/newstuff/simpleshapes.svg) .


<image>

We now turn to the <image> tag, which is quite like the <img> tag in HTML. As we do, we are likely to be reminded of the importance, for accessibility, of the "alt" attribute in HTML <img>. This brings up the larger issue of accessibility in SVG ( see http://srufaculty.sru.edu/david.dailey/W3CCourse/accessibillitySVG.html) .

You will probably be able to use most of the other drawing primitives without much difficulty, but the <image> tag deserves special attention, so let's look into it a bit. Like the <img> tag in HTML, <image> in SVG refers to an external image file which might be, typically, in .jpg, .png, .gif, or .svg format. [The specification requires support only for PNG and JPG, though, in practice, all browsers seem to support GIF as well.] That file exists outside the SVG document itself and can either be referenced through a "relative" path (a filename, typically within the same directory as the SVG document itself) or an "absolute" path (typically a URL pointing to a file on the Internet). The oddity is that the reference to the external file requires slightly odd syntax (recall that SVG is XML) and uses an attribute that looks like:
xlink:href="fireenginefromWebsters1911.gif"

To make matters even odder, the mere use of this external reference is enough (in most browsers) to require more of what some might consider to be mystical incantations in the <svg> tag itself:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >

Wrapping together, the xlink namespace declaration in the SVG tag, the xlink:href inside the <image> tag itself, some presentation attributes for the <image> tag, and a <title> and <desc> to aid accessibility, we have something like the following:
  1. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  2. <title>Illustration of the use of SVG image tag</title>
  3. <desc>An engraving of a fire engine taken from the 1911 Webster's Dictionary</desc>
  4. <image x="15%" width="30%" y="15%" height="30%" xlink:href="fireenginefromWebsters1911.gif" />
  5. </svg>

The use of percentages in this example is worth explaining: the image's left edge will be positioned 15% of the way from the left side of the viewing window to the right side, and the image will have width defined as 30% of the width of the viewing window. The above file will be rendered as follows:
Inserting a bitmapped image into SVG

This may seem like an awfully convoluted way of adding an image to a Web page. But that's because we haven't started adding further graphics on top yet!

We'll do that next!.

Adding more shapes: <rect>, <circle>, <ellipse>


We're going to pick up where we left off in the previous lecture. You'll recall that we had used XLink to include an image within an SVG document. Now let's take several steps at once and use the <rect> , <circle> , <ellipse> , and <image> elements to create a small collage that looks something like the file depicted here in the Chrome and Opera browsers (with different window sizes).
Collage viewed in ChromeCollage viewed in Opera
Collage involving <rect>, <circle>, <ellipse>, and <image> as seen in Chrome (left) and Opera (right) browsers

First, it is important to note that all of the content seems to be "centered" on the web page, and that this seems to be true regardless of the dimensions of the browser window. This should be a hint that numeric values of positioning attributes are probably laid out using relative coordinates (like 50%) rather than absolute values (like 500px).

Second, as discussed in the Primer, SVG lays content down into the web page with things defined later being added physically on top of (that is, in front of) content that was defined earlier. That being said, there is an apparent "stacking order" in which the purple oval looks to be atop the light blue rectangle which is, in turn, above, the orange circle that, itself is in front of the picture of the fire engine. In such a document (in which the stacking order can be uniquely determined after the image has been drawn), we can determine the order in which to build our graphical elements: <image>, <circle>, <rect> and then <ellipse> in that order. So let us begin in that order.

We'll begin with a generic template that includes the <svg> tag and the namespace declarations to make the content work across browsers that require them. Let's also include a <title> tag that gives people who might read the source code as well as search engines an idea of what we are up to:

  1. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  2. <title>Collage involving rect, circle, ellipse, and image tags </title>
  3. </svg>

Next, lets try an image tag pointing to our public domain engraving of a fire engine:

<image x="15%" width="70%" y="30%" height="15%" xlink:href="fireenginefromWebsters1911.gif" />

We might play with values of the placement attributes of "x", "y", "height" and "width" a bit until the image seems to occupy the right position on the page, but estimating those values exactly with the eye is likely to be a frustrating activity. Let us just try to aim the picture in what looks like a similar position. As soon as we open the document in any browser other than IE/ASV though we find that our intention to make the height and width stretched in a this particular way has been overridden. This is because, by default, most browsers assume the aspect ratio of an image to be confined by the intrinsic size of the image (given by its height and width information in the format of the actual file). To accomplish the desired stretching, then, we must add a flag to override the browser's wish to override our desire:

<image x="15%" width="70%" y="30%" height="15%" xlink:href="fireenginefromWebsters1911.gif"
preserveAspectRatio="none"/>


Next, let us consider the orange circle overlaid atop the image. It may or may not appear to be a circle. It well might be an ellipse with values of rx and ry that are numerically close. It so turns out though, that the above circle, actually was drawn by a <circle> tag. Since the Opera and Chrome variants show that the size of the circle seems to expand with the size of the window, again we will gravitate toward values expressed as a percentage of the viewing window.

<circle cx="50%" cy="50%" r="25%" />

The above code would make a black circle of about the desired size.

Now, how might we make the interior of the circle transparent? Actually there are two ways, but the simplest would be to use a value of "none" on the fill attribute as follows:

<circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25">

In order to make the circle visible, we had to define a stroke and a stroke-width, since otherwise nothing would be guaranteed to show up.

Turning our attention to the rectangle, we try something like:

<rect x="10%" width="80%" y="50%" height="10%" fill="aqua" stroke="black" stroke-width="6" />

This seems to work fairly well, though the color might need a bit of adjustment (appearing a mite too dark), and the dashed line around the border is missing. The Primer's discussion of dash-array in the section pertaining to <line> is relevant however.

<rect x="10%" width="80%" y="50%" height="10%" fill="#8ff" stroke-dasharray="4" stroke="black" stroke-width="6" />

The dash-array attribute specifies, in this particular case, that the border will be turned on and then off again every four pixels.

Just to recap, we now have a document that looks like this:

  1. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  2. <title>Collage involving rect, circle, ellipse, and image tags </title>
  3. <desc>image is an engraving of a fire engine taken from the 1911 Webster's Dictionary</desc>
  4. <image x="15%" width="70%" y="30%" height="15%" xlink:href="fireenginefromWebsters1911.gif" preserveAspectRatio="none"/>
  5. <circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25"/>
  6. <rect x="10%" width="80%" y="50%" height="10%" fill="#8ff" stroke-dasharray="4"
    stroke="black" stroke-width="6" />
  7.  </svg>

And it renders like this:
collage before oval
Collage before oval

Just one more tag remains to be developed, and I've provided an effect that has not yet been introduced in the book: transparency (referred to in the SVG spec as opacity, which is, unsurprisingly, the opposite of transparency).

We may, easily enough, create an oval atop all the other things, and centered at the center of the page, thusly:

<ellipse cx="50%" cy="50%" rx="10%" ry="40%" fill="yellow" stroke="purple" stroke-width="15" />

But while we know that we may either fill the interior with a color (hence making the oval opaque) or set fill="none" making it completely transparent, we clearly (pardon the pun), we have an interest in doing something in between. It turns out that for many objects (such as <circle> <ellipse> <rect> and <path>), we may adjust the opacity as follows:

opacity=".5"

We may use values of opacity from 0 (representing transparency) to 1 (representing opacity) or any number in between. This suggests that we try something like:
<ellipse cx="50%" cy="50%" rx="10%" ry="40%" fill="yellow" opacity=".45"
stroke="purple" stroke-width="15" />


This is close to what we want, however, if you actually try it, you'll find the picture looks like this:
collage with transparent oval
collage with transparent oval

This is not quite what we wanted since the border of the new ellipse is also partly transparent. We want just the interior to be partly transparent.

It so turns out, that in SVG, we may independently vary the fill-opacity and the stroke-opacity. If we want the entire object to have a certain amount of transparency, then we use the opacity attribute, Otherwise, we use fill-opacity and stroke-opacity independently.

<ellipse cx="50%" cy="50%" rx="10%" ry="40%" fill="yellow" fill-opacity=".45"
 stroke="purple" stroke-width="15" />


In the above code we may assume a default value of stroke-opacity="1".

The final code for our reverse-engineering of this simple collage looks like this:

  1. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  2. <title>Collage involving &lt;rect&gt; , &lt;circle&gt;, &lt;ellipse&gt;, and &lt;image&gt;</title>
  3. <desc>image is an engraving of a fire engine taken from the 1911 Webster's Dictionary</desc>
  4. <image x="15%" width="70%" y="30%" height="15%" xlink:href="fireenginefromWebsters1911.gif" preserveAspectRatio="none"/>
  5. <circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25"/>
  6. <rect x="10%" width="80%" y="50%" height="10%" fill="#8ff" stroke-dasharray="4" stroke="black" stroke-width="6" />
  7. <ellipse cx="50%" cy="50%" rx="10%" ry="40%" fill="yellow" opacity=".45"
    stroke="purple" stroke-width="15" />
  8.  </svg>

The rendered SVG can be seen here and looks like this (in a browser that can see SVG within HTML <img> tags):
collage of SVG elements

<text>

Putting text on a page is a natural thing to do. Future versions of SVG are likely to offer more possibilities than we have at the moment and browser support for text seems to be poised for improvement. Right now one should be aware that there are some problems associated with the appearance of text across browsers.

Nevertheless a few simpler things may be done reliably, simply and consistently. Here's a sort of simplest case:
  1. <text x="0" y="100" font-size="80" fill="red">
  2. Doing text</text>
simple text example
The dimensions of the text (obtained by using the method getBBox(), discussed in later chapters) varies a bit between browsers as shown in table 2 below. Interestingly, similar differences remain in effect even when font-family="monospace" is specified .

Browser Left Top Bottom Right
IE 6.15 42.72  115.79 359.48
FF 8 42 117 358
Opera -0.14 28.47 118.53 337.37
Table 2: Results returned by different browsers
for the getBBox() function

Similar results would be observed for HTML since a fundamental premise of the web has been that font support and layout is a choice left to the browser software.

The W3C SVG specification reveals that SVG fonts should be equivalent to those of CSS-2, but it may be important to specify generic font families (specifically serif, sans-serif, cursive, fantasy or monospace) to increase the probability that your visitors' browsers can see them. Even so, as the following illustrates, current browser support for font-families is lagging behind the specifications.
fonts across browsers
Appearance of fonts in different browsers: ASV+IE, FF1.5 and Opera 9 respectively

The specification also provides dozens of other ways of controlling the appearance of text, some of which have been implemented in existing browsers. Below (and visible at http://srufaculty.sru.edu/david.dailey/svg/newstuff/text6.svg ) is a sampling of some effects that are possible in at least some browsers already:

text styling in SVG
As of Spring 2009 all five of the primary browsers now support text effects such as shown below.

  1. <defs>
  2. <path id="curve" d="M 10 100 C 200 30 300 250 350 50"
  3. stroke="black" fill="none" stroke-width="5" />
  4. </defs>
  5. <text id="T" font-family="arial" font-size="16">
  6. <textPath xlink:href="#curve">
  7. Hello, here is some text lying along a bezier curve.
  8. </textPath>
  9. </text>
text on a bezier curve
textcurve.svg

The path above is defined inside a <defs> tag which serves to define the path but without rendering it. Various flags exist which adjust the positioning of the text along the path, many of which seem not yet to be supported by browsers. One exception is the startOffsetattribute of the <textPath> which provides a distance in pixels from the beginning of the curve, where the text will actually begin. When animated with SMIL (we will cover this later), this attribute makes the text appear to crawl along the curve with speed determined by the SMIL.

The rate at which browser improvement is bringing new features forward would render quite out-of-date any attempt to state a list of currently supported features, but suffice it to say, there are major browser differences here at the current time.

More notes on text in SVG:


Exercises