tool / svg shapesruns in your browser
SVG shape to path converter
Paste an SVG. Every rect, circle, ellipse, line, polyline and polygon becomes the <path> it is equal to, with exact arcs and the same attributes. Watch both versions draw, see what changed, and copy the converted SVG.
- Shapes
- 6
- Arcs per circle
- 2 or 4
- Output
- 4
- Uploads
- 0
Convert shapes to paths
The sample is a camera drawn from all six shapes and one path. On the left it is drawn as pasted, on the right converted, both by scrollDraw with its default selector: watch the shutter button, an <ellipse>, and the rounded body.
Before · as pasted…
After · converted…
What each shape becomes
The SVG 2 spec defines every basic shape as a path, and these are those paths in absolute commands, with a circle or an ellipse as two half arcs (the spec writes four quarter arcs, which the 4 arcs setting gives). Each starts where the browser starts the shape: a rect, circle or ellipse runs clockwise, a line or poly shape in the order of its points. So a dash animation on the path begins at the same point as one on the shape (fig. 1).
| Shape | Path | Starts at |
|---|---|---|
| <rect> | M x y H x+w V y+h H x Z | Its top-left corner. |
| <rect rx ry> | M x+rx y H x+w−rx A rx ry 0 0 1 x+w y+ry V y+h−ry A rx ry 0 0 1 x+w−rx y+h H x+rx A rx ry 0 0 1 x y+h−ry V y+ry A rx ry 0 0 1 x+rx y Z | rx along the top edge, where the top-left corner’s curve ends. |
| <circle> | M cx+r cy A r r 0 1 1 cx−r cy A r r 0 1 1 cx+r cy Z | Its rightmost point. |
| <ellipse> | M cx+rx cy A rx ry 0 1 1 cx−rx cy A rx ry 0 1 1 cx+rx cy Z | Its rightmost point. |
| <line> | M x1 y1 L x2 y2 | x1, y1. |
| <polyline> | M x0 y0 L x1 y1 L x2 y2 … | The first point. |
| <polygon> | M x0 y0 L x1 y1 L x2 y2 … Z | The first point; Z closes it. |
<!-- before -->
<circle cx="50" cy="50" r="40"/>
<rect x="10" y="10" width="80" height="40"/>
<rect x="10" y="10" width="80" height="40" rx="8"/>
<polygon points="10,10 90,10 50,80"/>
<!-- after -->
<path d="M90 50 A40 40 0 1 1 10 50 A40 40 0 1 1 90 50 Z"/>
<path d="M10 10 H90 V50 H10 Z"/>
<path d="M18 10 H82 A8 8 0 0 1 90 18 V42 A8 8 0 0 1 82 50 H18 A8 8 0 0 1 10 42 V18 A8 8 0 0 1 18 10 Z"/>
<path d="M10 10 L90 10 L50 80 Z"/>rx, ry and the edge cases
A rect’s corners follow a few rules that are easy to get wrong by hand, and some shapes draw nothing at all. The converter reads each one the way the browser does, and the note below lists where browsers disagree.
| Case | The browser | The converter |
|---|---|---|
| rx, no ry | Uses rx for both radii (and ry for both when only ry is set). | The same, and says so. |
| rx > width ÷ 2 | Uses half the width. ry is cut to half the height on its own. | The same: 120 × 40 with rx 30 has 30 × 20 corners. |
| rx or ry 0 | Square corners. | Square corners, starting rx along the top edge as the spec says. |
| negative radius | Ignored, as if it were not set. | The same. |
| width, height or r 0 | Draws nothing. | Left as it is: a path with those numbers could draw a line, or a dot with round caps. |
| mm, cm, in, pt, pc | Converted at 96 px to the inch. | Converted the same way, into user units. |
| %, em, vw | Resolved from the page’s layout. | Left as it is: the layout is not here to read. |
| odd points | Drops the last coordinate. | The same. |
| unreadable numbers | Ignores a value it cannot read, such as width="40.", as if it were not set. Unreadable points draw nothing. | The same: a rect left with no width is left as it is, and so are unreadable points. |
| style, marker, <animate> | A size in style="…", a marker on a rect, circle or ellipse (not drawn), SMIL changing r or width. | Left as it is: as a path it would lose the size or the animation, or gain the marker. |
rx="5" ry="0" Firefox and Safari start the outline 5 along the top edge and Chrome at the corner. With rx="auto" Chrome draws a rect with square corners, and an ellipse not at all. In points, Firefox reads a second dot (50.5.5) as an error and draws nothing, where Chrome and Safari read 50.5 and 0.5. The converter follows the spec, or Chrome and Safari for the dot, and says so in its notes.Why convert shapes to paths
To draw every shape. scrollDraw animates what its selector option matches, and the default is 'path, polyline, line, polygon, rect, circle'. An <ellipse> is not in it, so it sits there fully drawn while the rest of the drawing animates. As a path it draws.
To measure every shape the same way. scrollDraw sizes the dash of a <rect> as 2 × (width + height), which is longer than a rounded rect’s outline, so its line is whole before the scroll is done. A path is measured along its curves with getTotalLength(). The converter’s table shows both numbers.
To morph. morphTo moves a path’s d toward another, number by number, and only works on a <path>: on a shape it does nothing. A circle and an ellipse converted with the same arcs setting share their commands (M A A Z), as do two polygons with as many points, so one morphs into the other. A rect and a circle do not, and scrollDraw warns in development.
For anything that takes path data. CSS offset-path: path(), clip-path: path() and the path attribute of SMIL’s <animateMotion> take a d string. The Path data tab gives just those strings.
// <div id="badge"><svg viewBox="0 0 200 100"><path d="M150 50 A50 50 0 1 1 50 50 A50 50 0 1 1 150 50 Z" fill="none" stroke="currentColor"/></svg></div>
import { scrollDraw } from 'svg-scroll-draw';
// A circle and an ellipse converted with the same arcs setting share their
// commands (M A A Z), so one can morph into the other as it draws.
scrollDraw('#badge', {
morphTo: 'M150 50 A50 30 0 1 1 50 50 A50 30 0 1 1 150 50 Z',
});import { scrollDraw } from 'svg-scroll-draw';
// Or keep the <ellipse>: the default selector, plus ellipse.
scrollDraw('#drawing', {
selector: 'path, polyline, line, polygon, rect, circle, ellipse',
});Shape to path questions
How do I convert an SVG circle to a path?
Write it as two half arcs from its rightmost point: M cx+r cy A r r 0 1 1 cx−r cy A r r 0 1 1 cx+r cy Z. So <circle cx="50" cy="50" r="40"/> becomes <path d="M90 50 A40 40 0 1 1 10 50 A40 40 0 1 1 90 50 Z"/>. It takes two arcs because an arc that ends where it starts draws nothing. The converter above writes this for every circle you paste and keeps its other attributes.
How do I convert an SVG rect to a path, with rounded corners?
With square corners it is M x y H x+width V y+height H x Z. With rx and ry it is four straight sides and four quarter arcs, starting rx along the top edge: <rect x="10" y="10" width="80" height="40" rx="8"/> becomes M18 10 H82 A8 8 0 0 1 90 18 V42 A8 8 0 0 1 82 50 H18 A8 8 0 0 1 10 42 V18 A8 8 0 0 1 18 10 Z. If only rx is set, ry takes the same value; a radius over half its side is cut to half, as the browser does.
How do I convert an ellipse to a path?
The same way as a circle, with its two radii: M cx+rx cy A rx ry 0 1 1 cx−rx cy A rx ry 0 1 1 cx+rx cy Z. <ellipse cx="60" cy="40" rx="50" ry="25"/> becomes M110 40 A50 25 0 1 1 10 40 A50 25 0 1 1 110 40 Z.
Why does my SVG ellipse not animate with svg-scroll-draw?
scrollDraw draws the elements its selector option matches, and the default is 'path, polyline, line, polygon, rect, circle', with no ellipse. The ellipse is left as it is, fully drawn, while the rest of the drawing animates. Convert it to a path here, or pass selector: 'path, polyline, line, polygon, rect, circle, ellipse'.
Does converting shapes to paths change how the SVG looks?
Not where browsers follow the spec. Each path is the outline the SVG 2 spec gives the shape, with the same fill, stroke, transform, id and class, starting at the same point and running the same way round, so dashes line up too. A few things could change it, and the converter checks for them: CSS that selects rect or circle by name or sets a size, a size in style="…", a marker (browsers draw markers on paths but not on a rect, circle or ellipse), and an animation of r, width or another attribute a path does not have. Where Chrome departs from the spec (rx="auto", or where a rect with one radius 0 starts its outline), the path matches Firefox and Safari, and the notes say so.
How do I convert a polygon or polyline to a path?
A polyline is M to its first point, then L to each next one; a polygon is the same with Z at the end to close it. <polygon points="10,10 90,10 50,80"/> becomes M10 10 L90 10 L50 80 Z. With an odd number of coordinates the last one is dropped, as the browser does.
Is it safe to paste my SVG here?
Yes. Nothing is uploaded: the SVG is read in your browser as data and never run. The previews are rebuilt from drawing elements only, so a script, an event handler or an outside link in it is left out of them, and the converted SVG you copy keeps everything else as you pasted it.
Drawing the paths on scroll with svg-scroll-draw 2.23.3: the docs, or the SVG path viewer to measure and check them.