Chapter 8

SVG & Path Motion

Line drawing, morphing, and motion along a path.

stroke-dashoffsetflubber@propertySMIL
Path data, stroke-dashoffset line drawing, morphing topology constraints, and motion along a path. flubber and MorphSVG interpolate shapes.

An SVG path is two things at once: a shape to fill or stroke, and a track with measurable length you can draw onto, morph, or send objects gliding along. This chapter works all three angles — line drawing, shape morphing, and motion along a path.

Path data: the d attribute

Every path is a string of commands in the d attribute. Uppercase letters take absolute coordinates, lowercase take relative ones. Five commands cover the vast majority of motion work:

M
moveto lift the pen, jump to (x,y) — starts a subpath
L
lineto straight line to (x,y)
C
cubic Bézier two control points + endpoint — smooth curves
Q
quadratic Bézier one control point + endpoint
Z
closepath line back to the subpath start

Technique 1 — Line drawing with stroke-dashoffset

The classic “self-drawing” effect is a trick with the dashed-stroke properties. Set stroke-dasharray equal to the path's total length so there is exactly one dash as long as the whole line and one equally long gap. Then animate stroke-dashoffset from that length down to 0: the dash slides into view and the line appears to draw itself.

Self-drawing path (scrub + auto-draw) live demo

Technique 2 — Shape morphing

Morphing interpolates the point positions of path A toward path B. Below, pick any two shapes and scrub between them. The shapes here have wildly different command counts (a 4-point square, a 9-point star, a heart of cubics) — yet they blend smoothly because flubber resamples them with maxSegmentLength: 2 before interpolating.

Shape-morph editor — flubber interpolate() live demo

Technique 3 — Motion along a path

Two ways to send an object down a track. The portable, works-everywhere route is to sample the path geometry yourself: path.getPointAtLength(fraction × total) returns the point, and you place your element there each frame. The newer, compositor-friendly route is the CSS Motion Path module — offset-path: path(...) plus offset-distance (and optional offset-rotate to auto-orient).

Dot along a path — getPointAtLength sampling live demo

Sampling getPointAtLength(pos × total) each frame.

CSS Motion Path (offset-path / offset-distance) Baseline 2024
Chrome/Edge
Firefox
Safari

offset-path with path()/ray()/url() and offset-distance/offset-rotate reached Baseline across Chrome, Firefox and Safari. Use it for compositor-driven, declarative path motion; fall back to getPointAtLength() sampling for older engines or when you need per-frame control.

SMIL and the libraries

SMIL (<animate>, <animateMotion>) is SVG's own declarative animation. Chrome announced its deprecation in 2015, but suspended that deprecation in 2016 — so SMIL is alive and broadly supported today. For new work the guidance is still CSS or the Web Animations API, which integrate with the compositor and the rest of your motion stack.

For production morphing, two library options stand out. GSAP's MorphSVG plugin — which became free in 2024 when GSAP's bonus plugins were opened up — handles point-count mismatches, gives a shapeIndex control to fix twisting, and morphs to raw shapes. Anime.js v4 offers svg.morphTo() for path interpolation and svg.createDrawable() for the line-drawing effect without measuring lengths by hand.

Playground: your own self-drawing line

Native CSS only — no libraries. Edit the path's d to draw any shape, and tweak the @keyframes dash timing. Because the path declares pathLength: 1, the dasharray and dashoffset both live in 0..1 space, so no measuring is needed.