Home > Sample chapters

Creating and Editing SVG Graphics

Paths in SVG

The <path> element is the most flexible drawing primitive in SVG. It contains subcommands that allow it to mimic all of the other basic shapes. As such, it is a bit trickier to learn.

Like other drawing primitives such as <rect> and <ellipse>, <path> can take attributes such as fill, stroke, and dash array. On the other hand, <path> uses a special syntax to describe the way it actually visits points on a plane. It borrows some of its origin (at least ideologically) from turtle graphics (http://en.wikipedia.org/wiki/Turtle_graphics), which are used in the Logo programming language to help introduce younger children to the basics of computer programming.

The SVG <path> element is very expressive due to the range of powerful path commands that it uses. As with the HTML5 <canvas> element, paths can be used to draw pen-up and pen-down movements, quadratic and cubic Bézier curves, and elliptical arcs, all within a single path. That is, you move the pen (or drawing point) from position to position, raise it and lower it, and make strokes of varying types. These instructions within the <path> syntax are called subcommands of the path object. In SVG, you’ll find them in the data attribute (d) of the <path>.

Paths typically begin with the M subcommand, which instructs the drawing to begin at a specific (x,y) point, such as (100,100), like so:

d = "M 100,100 ..."

From there, you continue adding points—that is, (x,y) pairs—describing segments to be joined along the path. The following section shows how this works.

<path> Subcommands: M and L

Start by specifying where the drawing will begin. As the first command for the d attribute, you insert a notation such as M x y, where x and y are numbers. You can think of M x y as meaning “Move the pen to the coordinates (x,y).” From there, you have the option of drawing a line (L), a quadratic curve (Q), a cubic curve (C), or an arc (A). For example, d=“M 50 50 L 150 150” would draw a diagonal line from the point (50,50) to the point (150,150).

httpatomoreillycomsourcemspimages1261187.png
<path stroke="black"
      d="M 50 50 L 150 150"/>
<path d="M 150 50
      L 250 150 350 100"/>

You should note several things about this example:

  • The second path does not specify a stroke; by default, the figure is filled with black. If you specify fill=“none”, the figure will be invisible unless you specify a stroke.
  • You can, for the sake of legibility, use commas between pairs of coordinates, in which case the space after the comma is optional.
  • You can omit the command letter on subsequent commands if the same command is used multiple times in a row, as shown in the second path, where the L command is followed by two pairs of values. Note also that if a MoveTo command (M or m) is directly followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit LineTo commands.

Fill Properties: nonzero and evenodd

Since a path is filled with black by default, it is natural to wonder what happens when a path crosses itself. As mentioned in Table 2-1, the default fill-rule value is nonzero, which means that by default, the union of the regions traversed by the path is filled unless you specify otherwise. You can find more information on this in the “Fill Properties” section of the SVG specification, at http://www.w3.org/TR/SVG/painting.html#FillProperties.

Here is an example to show the difference between the fill-rule values nonzero and evenodd.

httpatomoreillycomsourcemspimages1261189.png
<path d="M 70,290 L 150,150 200,250 40,250 100,150 170,290"/>
<path d="M 70,290 L 150,150 200,250 40,250 100,150 170,290"
      fill-rule="evenodd" transform="translate(250,0)"/>

This example demonstrates the default fill technique, as well as the evenodd fill rule on a shape that intersects itself in more than one place.