onComplete · fill transitionA logo that draws itself in is the most-requested scroll effect there is, and it is almost always built with GSAP DrawSVG for what amounts to one animated stroke-dashoffset. This example does it with a single component and no plugin registration. The interesting part is not the draw — it is what happens at 100%: onComplete fires, the outline floods with brand colour, and a second animation runs off the back of it.
The Discord logo strokes itself in as an outline, then floods with color on completion — followed by a right-eye blink. Uses onComplete to trigger the fill transition and blink sequence.
// 1. stroke draws on scroll (fill starts transparent)
// 2. onComplete: fill floods in + right eye blinks
<ScrollDraw easing="ease-out" speed={0.95} once
onComplete={handleComplete}>
<svg viewBox="0 0 127.14 96.36">
<path d="M107.7,8.07…"
fill={filled ? '#5865F2' : 'transparent'}
stroke="#5865F2" strokeWidth="2.5"
style={{ transition: 'fill 0.45s ease' }} />
{/* Left eye — floods white on complete */}
<ellipse cx="42.45" cy="53.03" rx="11.42" ry="12.67"
fill={filled ? 'white' : 'transparent'}
style={{ transition: 'fill 0.45s ease' }} />
{/* Right eye — blinks via scaleY */}
<ellipse cx="84.69" cy="53.03" rx="11.42" ry="12.67"
fill={filled ? 'white' : 'transparent'}
style={{ transform: `scaleY(${blinking ? 0.05 : 1})`,
transformBox: 'fill-box', transformOrigin: 'center',
transition: 'fill 0.45s ease, transform 0.1s ease-in-out' }} />
</svg>
</ScrollDraw>npm i svg-scroll-draw
MIT licensed, zero runtime dependencies. Every API is a separate entry point, so you only ship what you import. Full API reference →
Signature handwriting animation
Make a signature write itself as the page scrolls — the classic handwriting effect in a few lines of SVG and one function call. No GSAP, no canvas.
Line chart that draws on scroll
Animate a line chart as it scrolls into view — axes first, then the data line tracing in with a colour shift. Copy-paste code, zero chart dependencies.