Curved Text in SVG
Curved text in SVG isn't too hard, as long as you understand how to define different kinds of curved
<path> elements in SVG. When you have a curved
<path> defined in a
<defs> elements (usually just inside your root
<svg>), to make the text inside a
<text> element follow that
<path>, all that's required is to insert a
<textPath> inside the
<text>, with an
xlink:href attribute that links to the
id of the defined
<path>. The actual text for display also gets added inside the
<textPath>, like so:
<text> <textPath xlink:href="#yourPath"> Your text </textPath> </text>
Unit circle, for reference:
Here, to define a path that is a partial arc of a circle I've used a combination of the
a commands in the SVG path data mini-language.
m is simply
moveto: when you start your path data with
mx,y, you're specifying the x and y coordinates where your path will start. Here we define the starting x and y coordinates with an
x of half the width (i.e., horizontal center of the SVG) minus the radius of the circle and a
y of half the height (i.e., vertical center of the SVG) in order to start the curve at
(-1,0) on the unit circle. This works of course because we centered our circle (within which we want to have our curved text fit) at exactly the horizontal and vertical center of the SVG.
a is a general elliptical arc command.
The first two arguments are
rx, ry, the radii of the ellipse. When you're drawing a circle, as we're doing here, the radii are the same, of course, so we start our arc command with
a190, 190. (We don't want our text's baseline to sit directly on the circle in which we're drawing it, so we've taken 95% of the circle radius to use as the radius for our
The next three arguments are the toughest to get a handle on. The first is the x-axis rotation of the ellipse. Since we're not actually drawing an ellipse, but a circle, nothing we put here will matter, so we leave it zero. The second is a boolean flag for whether to choose the longer or the shorter arc when more than one arc between the start and end points of the arc is possible, but again since we're drawing a arc, it doesn't matter what we put here; the "longer" and "shorter" arcs have the same length in the special case that an ellipse is a circle. Finally, we have the
sweep-flagargument, which controls whether the arc is drawn starting from the starting point and moving counter-clockwise (the
0option) or clockwise (the
1option). We're starting midway up on the left of the circle and we want to draw the lower half-circular arc, so we choose
0to draw counter-clockwise (i.e., from 6 o'clock to 3 o'clock).
Finally we give the end coordinates of the arc. Since we're using the
acommand (for relative coordinates, versus
Afor absolute coordinates), our coordinate system is relative to the
movetocommand we began with, and we don't have to repeat the calculations that went into calculating the
movetocoordinates. Instead we use the unit circle to reason that if our starting point was at unit
(0,0)since it's the center of our relative universe---then we want our end point to be twice the radius for the x-coordinate because we want to move to unit
(1,0)and it takes two radius lengths to do that.
Altogether, the final elliptical arc command is
a190,190 0 0 0 380,0.
And the entire path definition
m485,250 a190,190 0 0 0 380,0.
The last couple of things to note here are two of the attributes we've defined on the
<textPath>. We use a combination of
startOffset at 50% and setting the
text-anchor to the
middle option to ensure that our text is centered on the curved path.