DrawSVG - stroke reveals
.draw and .draw-split progressively draw an SVG stroke from 0% to 100% using GSAP's DrawSVGPlugin. Strokes only - filled shapes are out of scope. Both are spawn classes, so they get .scroll, .scroll-progress, .appear, .leave and all timing tunables for free.
<svg viewBox="0 0 200 80">
<!-- single-segment path -->
<path class="draw appear time-2" d="M10 40 C40 10 80 90 120 40 S160 10 190 40"
fill="none" stroke="currentColor" stroke-width="3" />
</svg>
<svg viewBox="0 0 200 80">
<!-- multi-segment path (multiple M commands) -->
<path class="draw-split appear time-2" d="M10 20 L80 20 M10 40 L80 40 M10 60 L80 60"
fill="none" stroke="currentColor" stroke-width="3" />
</svg>.draw - single stroke
Draws the target(s) as one stroke via drawSVG: "0%" → "100%". Works on any single-segment <path>, <line>, <polyline> or <circle> that has a visible stroke. Applied as from: { drawSVG: "0%" } so scroll reversal and leave animations return to undrawn correctly.
.draw-split - multi-segment paths
Browsers can't reliably dash-animate a path with multiple M commands as one stroke. .draw-split busts it apart first: each segment becomes its own <path> (attributes copied verbatim, original removed), then each segment is drawn sequentially with a slice of time-N proportional to its length - constant pen speed across the whole drawing. Result is cached on the element so StrictMode remounts don't churn the DOM.
If there's nothing drawable (empty selection or zero-length strokes) the helper returns an inert timeline rather than dividing by zero.
.fill-svg - fill after stroke (modifier)
.fill-svg is a modifier for .draw and .draw-split - add it alongside either class and the interior fills after the stroke finishes (draw → fill). Requires a fill colour on the element (fill attribute or CSS); the modifier animates fillOpacity: 0 → 1 so the colour appears only once the outline is complete. Leave / scroll reversal un-fills before un-drawing, and .scroll-progress scrubs draw then fill sequentially.
<circle class="draw fill-svg appear time-2 fill-time-1" cx="50" cy="50" r="38"
fill="currentColor" stroke="currentColor" stroke-width="3" />
<path class="draw-split fill-svg appear time-2 fill-time-0.6" d="M10 20 L80 20 M10 40 ..."
fill="currentColor" stroke="currentColor" />Fill timing is separate: fill-time-N sets fill duration (default 0.5× time-N), fill-ease-NAME overrides ease (default reuses draw ease). Without .fill-svg the element stays stroked with transparent interior.
Tunables
time-NSeconds to draw (split: total time, split proportionally by length)fill-time-NFill duration after draw (default 0.5 × time-N)ease-NAMEDraw ease (default power3.out)fill-ease-NAMEFill ease (default reuses draw ease)delay / priority-N / .orderSame spawn delay machinery.scroll / .scroll-progressEnter-replay or scrubbed draw → fill; leave reverses unfill → undraw<path class="draw scroll time-2 ease-power2.out" d="..." />
<path class="draw-split scroll-progress progress-start-20 progress-end-80" d="M10 20 L80 20 M10 40 ..." />
<circle class="draw fill-svg scroll time-2 fill-time-0.6 fill-ease-power2.out" cx="50" cy="50" r="38" fill="currentColor" />
<path class="draw-split fill-svg scroll-progress fill-time-1" d="..." />Stroke only - for outline-only reveals keep fill="none" with a visible stroke/stroke-width. Add .fill-svg with a fill colour (fill="currentColor" inherits the text colour) to fill after the stroke; it animates fillOpacity. Markers and multi-path groups are untouched. Draw state is drawSVG: 0% → 100% - the stroke IS the reveal. Splitting replaces the source path in the DOM and copies all attributes verbatim.