Getting to know the <path>

July 22, 2018

If you haven’t already checked out my first post in this series, then you may wish to read that first, as that covers the basics of SVG. This article attempts to dive into some of the more advanced parts of the SVG spec.

Once we understand the viewbox and know how to add some simple shapes to our graphics, we can then look to some of the more advanced tags in SVG to really get cooking. In this article, I will introduce you to the all-powerful path tag, which will give us the ability to draw shapes of any complexity.

Allow me to introduce perhaps the most important tag in SVG, the <path> tag. Once we know the <path> tag, we could decide to forget all about the other shape and line tags — as the <path> tag can recreate all of them.

But before we start erasing <circle> and <line> from our memory, Eternal Sunshine of the Spotless Mind-style, it should be noted that the syntax for creating a path is a little more difficult to master, especially if we want to do more complicated shapes.

The <path> to enlightenment

The <path> tag has only one attribute to understand, the definition attribute (d), but this attribute expects a particular syntax for defining all the information about the path. Here’s a very simple example of a <path>, to get us started:

<svg viewBox="0 0 10 10">
  <path d="M 0,0 H 10 V 10 Z" />

The d attribute takes a series of letters and numbers, which plot the path onto our SVG viewbox. Each letter signals the beginning of a letter command, and the numbers following that letter are the values which that command uses to create the next part of the path.

Letter commands are case-sensitive — an upper-case command (eg. M) specifies its arguments as absolute positions, while a lower-case command (eg. m) specified points relative to the current position.

Let’s break down this example, command by command, to see what commands we have available to us, and what each does:

Move to (M x y)

Used to move the path to a point, without drawing any sort of line between this and the previous point. Often thought of like picking up a pen and putting it down on the point to begin/continue drawing.

It is good practice to begin every path with the M command.

Line to (L x y)

Draws a straight line from the previous point to the x and y coordinates specified.

Vertical line (V y)

Draws a straight line up or down from the previous point to the x coordinate specified (y remains unchanged).

Horizontal line (H x)

Draws a straight line left or right from the previous point to the y coordinate specified (x remains unchanged).

Close path (Z)

Closes the current subpath by connecting the last coordinates with the first (If the two points are not the same, a straight line is drawn between them).

Okay, so that was a lot of work to recreate something the <rect> tag could do, but these commands can be used to draw far more complex shapes than simple rectangles.

Commas are ignored in the d attribute — If they help you keep track of your coordinates (as they help me), then feel free to add them to your code.

Now that we know how to use the d attribute with letter commands to draw shapes, we can now take a look at getting curvy.

Drawing curves with the path tag

The <path> tag has a few different ways of drawing curves, that fall under two general categories: bezier curves and arcs.

Bezier Curves

If we want to build curvy lines, bezier curves are our first port of call. These curves are defined with control points, and as such they are relatively easy to visualise and define.

To draw a bezier curve in our <path>, we can use some more letter commands, like we just learnt. There are 2 types of bezier curves that can be drawn: cubic and quadratic.

Cubic bezier curves

To create a cubic bezier curve, we use the C command.

C — Cubic curve (C dx1 dy1, dx2 dy2, dx dy)

The syntax for defining a cubic curve takes 3 sets of coordinates: the first point’s control point (dx1 dy1), the second point’s control point (dx2 dy2), and then then second point (dx dy).

Use the interactive demo below to drag the control point handles to see how the control points affect the curve on the line:

200, 100300, 300
<path d="M 100,200 C 200,100 300,300 400,200 " />

If we are chaining cubic bezier curves, we can use a shorthand version for more succint markup:

S — Shorthand cubic curve (S dx2 dy2, dx dy)

Using an S command produces the same type of curve as using C, but if it follows another S command or a C command, the first control point is assumed to be a reflection of the one used previously. Take a look at how that works:

200, 100300, 300600, 300
<path d="M 100,200 C 200,100 300,300 400,200 S 600,300 700,200 " />

Cubic bezier curves are quite simple to create, though not quite as simple as Quadratic bezier curves:

Quadratic bezier curves

The other type of Bezier curve, the quadratic curve requires just the single control point which determines the slope of the curve at both the start point and the end point.

Q — Quadratic curve (Q dx1 dy1, dx dy)

This control points defines the curve, as seen here:

200, 100
<path d="M 100,200 Q 200,100 300,300 400,200 " />

So quadratic curves are simpler to create than cubic curves, but don’t give us as much control over the curve itself.

T — Shortcut quadratic curve (T dx dy)

As with the cubic curves, there is a shorthand way of writing quadratic curves, using the T letter command. This will assume a reflected control point, similarly to the shorthand cubic command. So in this case, all we need to tell the curve is the next point of the line.

200, 100
<path d="M 100,200 Q 200,100 300,300 400,200 T 700,200" />

To recap what we have learned, these are the bezier curve commands we can use:

  • C — Cubic curve (C dx1 dy1, dx2 dy2, dx dy)
  • S — Shorthand cubic curve (S dx2 dy2, dx dy)
  • Q — Quadratic curve (Q dx1 dy1, dx dy)
  • T — Shortcut quadratic curve (T dx dy)

Now to move on to the second category of curves we can create in an SVG — arcs.

Arc it up

Arcs are arguably the most difficult bit of learning SVG, but are the most powerful tool in it’s arsenal for drawing curves.

To start an arc, we use the A letter command. Then we have to pass a whopping 7 numbers to the definition:

A — Arc (A rx ry ellipses-rotation large-arc-flag sweep-flag x y)

The arc command draws a curved line which is based on a segment of the edge of an oval/ellipses. Here is an example of an arc, and we can see how the arc is just a segment of the ellipses edge:

To break it down, here’s what each of those values is, specifically:

rx ry: Radii of ellipse/s, respectively

Yes, radii is the plural form of radius, thank you very much. And okay, yes, I had to google it. Anyhow, the rx ry values lets us set the radius of the ellipses which will be used to form an arc.

ellipses-rotation: Rotation of ellipse/s

The next value let’s us rotate those ellipses, in a rather straightforward sense:

large-arc-flag: Flag to determine which ellipse line to draw to the end-point (1 for on, 0 for off)

The next value is a flag value, meaning it is either 0 for off, or 1 for on.

When a the ellipses cross over to form 2 arc, this flag determines whether to use the ‘long arc’ to create our arc (ie. the longer part of the ellipse).

sweep-flag: Flag to determine which ellipse direction to draw to the end-point (1 for on, 0 for off)

The sweep_flag specifies which side of the path the curve is drawn.

x y: Co-ordinates of endpoint

Oh yeah, and finally, we will need to specify exactly where on the ellipses we want to segment our curve:

When you put all those pieces together, the arc command looks a litle something like this:

<path d="M0 0 A 100 200 30 0 0 200 200" />

The arc syntax is a little difficult to explain, but makes a lot more sense when visualised. Have a play around with the demo below to get an understanding of how each value does:

X Radius: 250
Y Radius: 250
Axis rotation: 0
250, 250550, 550
<path d="M 250 250 A 250 250 0 0 0 550 550 " />

The bezier and arc commands can seem intimidating when first encountered, but once we’ve got a handle on how their syntax works, they reveal themselves to be the secret sauce to creating complex and exciting graphics with SVG.

Choose your own path

That’s about all there is to know about defining a <path> tag! Now we can start stringing those letter commands together and draw whatever the hell we damn well please.