SVG6: Curves in SVG

(Note: this is copied over from 2014, without much modernization)

SVG has good facilitities for drawing 2D curves. This is a good way to experiment with Bezier curves (since it supports them).

SVG curve drawing is through the “path” tag object. Unlike other objects (like lines and circles), paths don’t have a bunch of parameters: they take a single string that describes the entire path. Once you figure out how to make these strings, paths aren’t so hard.

A path is a piecewise curve. For each piece, you can either move the “pen” to a new location, or add a new piece of curve starting wherever the pen was last. The pieces can be line segments, quadratic or cubic Bezier segments, and elliptical arc segments (which includes circular arcs).

The official documentation is here, and has a lot of details you may not care about. But it also has some good examples.

Here are some simple examples, with commentary.

1<svg xmlns="http://www.w3.org/2000/svg" height="50" width="100">
2    <rect x="0" y="0" height="50" width="100" fill="#EEE"/>
3    <path d="M25,25 L75,25" fill="None" stroke="black" stroke-width="3" />
4</svg>

The key thing is the d parameter, where the path data goes. Notice that the path begins with an M (moveto) command that tells SVG where to move the pen to. The M command has two numbers (x and y). Then there’s an L command (or lineto) that tell SVG to draw a line connecting the current pen position to the new position.

Of course, we didn’t have to stop with just 1 M and 1 L. We could keep going

1<svg xmlns="http://www.w3.org/2000/svg" height="50" width="100">
2    <rect x="0" y="0" height="50" width="100" fill="#EEE"/>
3    <path d="M25,20 L75,20 L75,10 M25,30 L75,30 L75,40" fill="None" stroke="black" stroke-width="3" />
4</svg>

Notice here that after adding a line segment, I then moved to a new place and started drawing lines again.

A warning: the default is to fill objects with black. If you’re trying to draw a curve, this is probably not what you want to do. Be sure to set fill="None" if that’s what you mean to do. If you fill a path, SVG will connect the first and last points for you.

1<svg xmlns="http://www.w3.org/2000/svg" height="50" width="100">
2    <rect x="0" y="0" height="50" width="100" fill="#EEE"/>
3    <path d="M25,20 L75,20 L75,10 M25,30 L75,30 L75,40"  stroke="black" stroke-width="3" />
4</svg>

If you’re just drawing lines, there are probably easier ways to do it. But the nice thing about paths is that you can add other curve types in the paths. For example, you can attach a line to a Bezier Segment:

1<svg xmlns="http://www.w3.org/2000/svg" height="50" width="100">
2    <rect x="0" y="0" height="50" width="100" fill="#EEE"/>
3    <path d="M20,25 L50,25 C60,0,70,50,80,25" fill="None" stroke="black" stroke-width="3" />
4</svg>

Here, notice that we made a cubic Bezier segment (the C command). As you know, cubic Beziers have 4 control points. The first one is the position of the pen before the C command, so there are 6 numbers for the parameters of the C command (3 points, each with x and y).

You are welcome to make the curve be discontinuous by putting the control points anywhere you like. You can also mix and match curve types. This uses a quadratic bezier, two line segments, and an elliptical arc.

1<svg xmlns="http://www.w3.org/2000/svg" height="50" width="100">
2    <rect x="0" y="0" height="50" width="100" fill="#EEE"/>
3    <path d="M30,10 L70,10 Q85,25,70,40 L30,40 A15,15,0,0,1,30,10" fill="None" stroke="black" stroke-width="3" />
4</svg>

The parameters for the arc segments are confusing. They are rx, ry, theta, large-arc-flag, sweep-flag, x, y.

  • rx, ry are the radii of the ellipse
  • theta is the orientation of the ellipse (if the major axis isn’t aligned with the X/Y axes)
  • the flags tell which way around the ellipse to go. If you read the documentation a few times, you might get it. But probably you’ll set these by trial and error.
  • x,y is the position where the curve ends.

The nice thing about figuring this out (especially for Beziers) is that you can experiment with Bezier curves without having to figure out how to implement them. It’s also nice that SVG can fill the curved shapes (which is tricky to implement). Prev: SVG5: More Transforms and Composition