11 ms·
An interactive guide to SVG paths
- ZFleck 1y agoLoved this. Thought it was perfect for my skill level (I know what an .svg is; that's about it). I think what I learned will actually come in handy the next time I'm trying to adjust / optimize an icon. I really liked the sound effects! Spent perhaps too long just picking up and dragging stuff. Thanks!
- kevg123 1y agoAnything by Josh is gold.
- NoSalt 1y agoThis is a fantastic article, and the interactive visuals really drive it home!
- leeoniya 1y agoheh, im currently working on an svg pathstring to canvs2d command compiler [1] and had to dive into this topic last week, including converting arc commands from centerpoint parameterization to endpoint parameterization [2] [1] https://github.com/leeoniya/uMarks https://github.com/leeoniya/uMarks (WIP!) [2] https://www.w3.org/TR/SVG/implnote.html#ArcConversionCenterToEndpoint https://www.w3.org/TR/SVG/implnote.html#ArcConversionCenterT...
- joshuat 1y agoNaN published a really great page about SVG paths a while ago: https://www.nan.fyi/svg-paths https://www.nan.fyi/svg-paths
- AndrewStephens 1y agoI really could have used this last year when I was making a web adventure game with randomly created map. SVG is one of those frontend technologies that seem pointless until you really need them. Dynamically creating SVG in response to user actions in the game provided a very nice graphical representation of the adventure. Unlike the author of this piece, I found the lower-case relative commands extremely useful for creating shapes like arrows (or in my case, sectors of space) that can be translated around later.
- LorenPechtel 1y agoAnd SVG means you can make a single file that contains everything. Pretty much irrelevant on the web, but we lack a good container format for putting a web page into a single document on disk. I've done entire multi-layer maps in SVG, complete with clicking on the map taking you to any associated details. The part I never found a good answer for is when I wanted to use higher detail glyphs on higher resolution outputs. (Think of the sequence of lines typically used to represent stairs.)
- deleted 1y ago[deleted]
- dang 1y agoSame title, but different article: An interactive guide to SVG paths - https://news.ycombinator.com/item?id=36574645 https://news.ycombinator.com/item?id=36574645 - July 2023 (39 comments)
- DrewADesign 1y agoI enjoyed the linked explainer video about the math of Bézier curves.
- deleted 1y ago[deleted]
- simpaticoder 1y agoI wonder if Seymour Papert's Logo programming language influenced the SVG path syntax. M and L correspond directly to "pen up/pen down" and move.
- cloudfudge 1y agoM and L and C are abbreviations for "moveto" and "lineto" and "curveto" from Postscript (which SVG was based on). I thought pen up and pen down in logo were "PENUP" and "PENDOWN."
- LorenPechtel 1y agoIt looks completely ordinary to me--exactly the sort of thing I wrote in HP/GL2 stuff for plotters. Your only possible tool on a plotter is a pen, of course the language is based on pen movements.
- hinkley 1y agoCurves were tough for me when I did logos. And at one point I decided one would be better off rotated, and realized a transform would be far, far easier than trying to modify the paths to run on a slant.
- vFunct 1y agoWould the same bezier curves be used in font rendering? And do we have GPU bezier drawing functions or shader kernels available?
- ethan_smith 1y agoYes, TrueType fonts use quadratic beziers while PostScript/OpenType use cubic beziers, and modern GPUs offer acceleration through tessellation shaders and compute pipelines like NV_path_rendering extension.
- o11c 1y agoNote that while cubic bezier curves are nice for designing shapes, quadratic bezier curves allow a much more optimized renderer. It's usually worth approximating.
- danielvaughn 1y agoI always took for granted that devs knew about SVG, but I had come into the industry by way of design, so I had already been toying with vectors for years with Adobe Illustrator and Sketch. SVG is awesome. Heavily underinvested in the web spec, would love to see SVG2 get some attention.
- tracker1 1y agoWorth noting that SVG manipulation via JSX support (such as in React) can be incredibly useful in practice. I used this to add markers and highlights over scanned documents in the past, as well as bar charts, line graphs etc... all without having to add in massive module libraries. Most charting libraries are excessively large when you just want to show/chart a little data.
- fatih-erikli-cg 1y ago[dead]
- manveerc 1y agoVery nice! We had a use case where we needed to convert some images into SVGs. Since AI performed poorly at that task, we had to spend time reading and understanding the SVG code. This makes things much easier.
- didgeoridoo 1y agoWere they images of pelicans on bicycles?
- cousin_it 1y agoI wonder if there's a more intuitive way to define an elliptical arc given 2 endpoints. Dimension analysis shows we need 3 parameters. The SVG spec uses rx/ry/rotation, plus a couple booleans, but maybe there's a better parameterization without booleans? For example, it could be two coordinates of a control point - if the endpoints are A and B and the control point is C, the ellipse would be tangent to AC and BC - and an additional positive number for squishing the ellipse closer or farther from C, with values above 1 making the arc bubble outward. So it would occupy a natural spot between quadratic Bezier (with 2 parameters = 1 control point) and cubic Bezier (4 parameters = 2 control points).
- ks2048 1y agoI think an intuitive way is: Your starting point is on a circle at angle theta_1 and you want to draw an arc of length delta_theta (positive or negative). You could define the circle via center (x,y) or radius. Edit: it looks like the SVG docs include the math for converting to and from this representation, https://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter https://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpoin...
- conic_explainer 1y agoThe answer is YES. Get ready for a trip involving some projective 2D geometry.. If you recall the Greek's fascination with conic sections, an ellipse, hyperbola, parabola, and of course circle are all the same subject to projective 2D transformations. You can "slice through" an infinitely extending (double) cone with a plane and get conic sections, hence the name. So you could have two end points (interpolating control points as the curve goes through these points) and third extrapolating control point. So like a quadratic Bezier segment with its three control points, but allow the extrapolating ("middle") control point to have a homogeneous "w" coordinate. So think of three points (x0,y0), (x1,y1,w1), and (x2,y2); alternatively you can think of this as (x0,y0,1), (x1,y1,w1) and (x2,y2,1). It's effectively what is called a rational quadratic Bezier segment (rational in the same sense as the R in NURBS). It turns out it is always possible to re-parameterize three homogeneous general control points of the form (X0,Y0,W0), (X1,Y1,W1), and (X2,Y2,W2) into the canonical form (x0,y0,1), (x1,y1,w1) and (x2,y2,1) -- basically forcing unit w values for the end-points. In this canonical form, the w1 value has a natural interpretation. When w1==1, the curve is a parabolic segment (so is parameterized to match exactly SVG's quadratic Bezier segment). Hyperbolic segments have w1>1; elliptical segments have 0<w1<1 and with SVG's large-arc flag set false. When w1==0, that's a degenerate line segment (best parameterized as two line segments). When -1<w1<0, this is an elliptical segment consistent with having SVG's large-arc flag set true. When w1<-1, you get a hyperbolic segment that shoots out to infinity in two directions, as if emanating from w-negated extrapolated control point (x1,y1,-w1). As w1 tends to either negative or positive infinity, the conic degenerates to two crossing lines clipped by a dividing line (defined by the two interpolating control points). So the conic segment is what cousin_it is asking for.. rather than "2 parameters = [extrapolating] 1 control point" or "4 parameters = 2 [extrapolating] control points)", the canonical conic segment is "3 parameters = 1.5 control points(!) in cousin_it's usage. See this rather obscure but excellent paper: Eugene T.Y. Lee. 1987. The Rational Bezier Representation for Conics. In Geometric Modeling: Algorithms and New Trends, Gerald E. Farin (Ed.). SIAM, Philadelphia, 3-19. Google's Skia API actually supports a conic segment where you can supply a (non-negative!) value for w1. So you aren't allowed to draw the so-called "external" conics, but this is for a pretty good reason. Rendering gets pretty wonky when negative w values are allowed (normally such negative values are intuitively considered "behind the viewer" when thinking about 3D and so clipped). There's lots of cool geometric intuition that can be assigned to the actual conic segment control points and the value of w. For an elliptical segment, the w1 value is the cosine of half the angle where the two tangent lines at the conic segment end-points, (x0,y0) and (x2,y2), where tangent is with respect to the ellipse. We can use this geometric intuition to build a perfect unit 360-degree circle out of four conic segments. Take four (counter-clockwise winding) points on the unit circle (+1,0), (0,+1), (-1,0), and (0,-1) where the unit circle intersects the X and Y axes. The tangents at these points are vertical, horizontal, vertical, and horizontal lines respectively. A vertical and horizontal line meet at a right angle, so 90 degrees. Half of 90 degrees is 45 degrees; the cos(45 degrees) = 1/sqrt(2) ~= 0.7071. So now we can build four conic segments: 1: (+1,0), (+1,+1,1/sqrt(2)), (0,+1) # upper-right quadrant 2: (0,+1), (-1,+1,1/sqrt(2)), (-1,0) # upper-left quadrant 3: (-1,0), (-1,-1,1/sqrt(2)), (0,-1) # lower-left quadrant 4: (0,-1), (+1,-1,1/sqrt(2)), (+1,0) # lower-right quadrant It's pretty straightforward to see you can draw a 360-degree ellipse this same way, just scaling (to squish or stretch) the x and y values. > maybe there's a better parameterization without booleans Yes, there is; yep, the conic segment parameterization has no booleans. > SVG spec uses rx/ry/rotation, plus a couple booleans Honestly, the SVG partial elliptical arc specification looks reasonable at first glance but is honestly bonkers and hardly intuitive. If you play with an SVG tool that let's you modify rx/ry/rotation and the booleans, changing these can be really surprising. With a conic segment, it's just like a quadratic Bezier segment but with an extra control to "tug" at w1. Start at w1==1 and it IS a quadratic Bezier segment. Increase w above 1 and the curve "gets sharper" (increasingly hyperbolic). Decrease w below 1 and the curve "gets flatter" (increasingly elliptical). It's much like a tension control. Since negative w1 values are problematic, you can always construct "large arcs" (also known as "external" conic segments) from a spline of w>0 conic segments. This isn't particularly hard. You also get a big representational advantage with conic segments. All the scalars involved are scalar "coordinates" (x, y, and also w). Contrast this with SVG's partial elliptical arc parameterization where you need nine(!) values of desperate types: two lengths (radii), one angle (rotation), two booleans (large-flag, sweep-direction), and two control points (four coordinates). SVG's parameterization cannot draw hyperbolic segments! Yet, it allows for weird situations such as an angle greater than 360 (so the arc can loop around multiple times??). (SVG makes it look like an arc is specified with just 7 values, but that's a ruse because the initial end-point is borrowed from the prior command; 9 values is more honest to describe a "freestanding" partial elliptical arc.) And if I'm putting my curved segments including arcs on the GPU, it's really nice to have a buffer of consistently uniform floating-point coordinates, not values of disparate type. Even more compelling, (x0,y0,1), (x1,y1,w1), and (x2,y2,1) can be treated as homogeneous points that can be transformed by a 3x3 projective 2D matrix and the curve that results from the transformed control points is the same as transforming the curve's points. Want to apply a shear/scale/translate/rotate and even projection on an SVG parameterized partial elliptical arc?? Good luck, sucker. Hint for someone really wanting to do this: convert the SVG arc to a spline of one or more conic segments, transform those conic segment control points by your transform's matrix, then try to reassemble the transformed conic segments back into awkward SVG arcs. Basically, the SVG arc parameterization is to 2D transformations of arcs what Euler angles are to composing 3D rotations!
- andrewrn 1y agoWow someone put a lot of work into this. Always had trouble with the path element. Thanks!
- Springtime 1y agoJust something that would be worthwhile looking into is preventing blanking out the entire page if cookies (and by extension local storage) are disabled. The page loads fully briefly then blanks out to a full viewport React error. I see this on various sites where it's avoidable.
- amtunlimited 1y agoI'm really glad the article links to Freya's "Beauty of Bezier Curves" videos, it's genuinely one of the best math/graphics/explainer videos ever made https://youtu.be/aVwxzDHniEw https://youtu.be/aVwxzDHniEw
- tonyedgecombe 1y agoIt’s worth a watch even if you aren’t interested in the subject just because it’s so well done.
- royletron 1y agoOf all the technologies I got exposure to on my Comp Sci degree, SVG is the only one I really still use every day.
- p0w3n3d 1y agothose sounds are wonderful
- trebligdivad 1y agoYeh it gets an upvote even just for the plop and ticks :-)
- ludicity 1y agoEverything Comeau puts out is so goddamn good. I paid for his CSS course a year ago and the effort that went into the pedagogy is just spectacular.
- WillAdams 1y agoIs there a drawing program which focuses on the programmability aspect of SVG editing while allowing drawing in a natural fashion? I've done it in Inkscape, but it's a bit awkward --- there was a programming orienting tool mentioned here a while back, but it was light on the drawing aspect.
- jarek-foksa 1y agoGodSVG: https://www.godsvg.com/ https://www.godsvg.com/ Boxy SVG: https://boxy-svg.com/#demo-elements https://boxy-svg.com/#demo-elements Repath Studio: https://repath.studio/ https://repath.studio/ MacSVG: http://macsvg.org http://macsvg.org
- ekunazanu 1y agoI usually use this: https://yqnn.github.io/svg-path-editor/ https://yqnn.github.io/svg-path-editor/
- emschwartz 1y agoThis is so detailed and easy to understand. Thank you for writing this up.
- mark-r 1y agoThe aside about whitespace and punctuation was interesting. Is there an SVG tidy program out there that will make your files more readable?
- igtztorrero 1y ago10 years hearing about SVG and now with 2 minutes I understand, it's like Logo language, the turtle. Thanks for the tutorial!
- nayuki 1y agoWell done on the excellent interactive visual explanation! Having experience reading/writing SVG paths from scratch, here are a few additions for the "Lil' extras" section: * 'H' (horizontal) is a shorthand for 'L' (line) where the y-coordinate does not change. For example, "M 12,34 H 56" is shorthand for "M 12,34 L 56,34". There is of course a lowercase relative version too, 'h', so "M 12,34 h 56" means "M 12,34 l 56,0". * 'V' (vertical) is a shorthand for 'L' (line) where the x-coordinate does not change. For example, "M 12,34 V 56" is shorthand for "M 12,34 L 12,56". There is of course a lowercase relative version too, 'v', so "M 12,34 v 56" means "M 12,34 v 0,56".