SVG Logo Draw Animation: How the Stroke Reveal Works
By the Charmotion team · Updated

An SVG logo draw animation sets each path's stroke-dasharray to the path's length, offsets the dash by the same amount so the line starts hidden, then animates stroke-dashoffset to 0. Get the length with getTotalLength() or set pathLength="1" on the path. Filled logos need a stroked mask, or a fill that fades in after the line.
Key takeaways
- The effect is one dash as long as the path, slid into view by animating stroke-dashoffset.
- pathLength="1" lets plain CSS use the same values for every path; getTotalLength() gives real lengths for constant speed.
- It only works on strokes. Filled logos, outlined text and Figma exports often have no strokes to draw.
- For filled artwork, animate a thick white stroke inside an SVG mask over the real shapes.
- Use Lottie or Rive Trim Path when the same reveal must also run in iOS or Android apps.
Already have a character or logo? See examples in real app screens: splash, onboarding, loading and empty-state screens, with the animation that plays in each.
How does the SVG line drawing effect work?
It is a trick with dashes. stroke-dasharray defines "the pattern of dashes and gaps used to paint the outline of the shape." stroke-dashoffset defines "an offset on the rendering of the associated dash array." Both are animatable and both work as CSS properties.
- Make one dash exactly as long as the path, followed by a gap of the same length.
- Shift the pattern by the full length, so the gap covers the path and nothing shows.
- Animate the offset back to 0. The dash slides along the path and the line appears to draw itself.
CSS-Tricks' classic explainer puts the requirement first: "The shape must have a stroke." Everything below follows from that.
What is the simplest code for an SVG logo draw animation?
Set pathLength="1" on each path. MDN explains that the browser then scales distances so stroke-dasharray "will assume the start of the path being 0 and the end point the value defined in the pathLength attribute." Every path becomes 1 unit long, so one CSS rule fits all of them.
<svg viewBox="0 0 200 60" role="img" aria-label="Offscript">
<path class="draw" pathLength="1" d="M10 45 C40 5, 70 5, 100 40 S160 75, 190 15" />
</svg>
.draw {
fill: none;
stroke: currentColor;
stroke-width: 4;
stroke-dasharray: 1;
stroke-dashoffset: 1;
animation: draw 1.6s ease-in-out forwards;
}
@keyframes draw {
to { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
.draw { animation: none; stroke-dashoffset: 0; }
}
forwards matters: animation-fill-mode: forwards keeps "the computed values set by the last keyframe," so the logo stays drawn when the animation ends. The reduced-motion rule shows the finished logo straight away.
If you prefer real lengths, measure them in JavaScript. getTotalLength() returns "the total length of the path in user units":
document.querySelectorAll(".draw").forEach((path, i) => {
const len = path.getTotalLength();
path.style.strokeDasharray = len;
path.animate(
[{ strokeDashoffset: len }, { strokeDashoffset: 0 }],
{ duration: 1200, delay: i * 150, easing: "ease-in-out", fill: "forwards" }
);
});Should you use CSS, SMIL or JavaScript for the draw effect?
| CSS | SMIL (<animate>) | JavaScript | |
|---|---|---|---|
| Lives in | Your stylesheet or a <style> inside the SVG | The SVG file itself | Your page script |
| Reduced motion | A media query in the same file | Possible with a <style> fallback; plan it explicitly | Check matchMedia before starting |
| Start on scroll or click | Toggle a class | Awkward | Natural |
| Stagger by real length | Manual delays | Manual | Easy with getTotalLength() |
SMIL is the <animate> element, which "provides a way to animate an attribute of an element over time." MDN marks it Baseline widely available. Use attributeName="stroke-dashoffset", from="1", to="0" and fill="freeze" to keep the end state.
Where the SVG lives also decides the method. Used as an <img>, MDN says some browsers disable JavaScript inside it and block external stylesheets, so the animation must be written inside the SVG file. Inline SVG in your HTML can use all three. To start the draw when the logo scrolls into view, the Intersection Observer API is the standard tool; the Web Animations API (element.animate()) gives you play, pause and restart from script.
How do you draw-animate a filled logo?
Most logos are filled shapes, not lines, so the dash trick has nothing to draw. Three ways around it:
- Outline, then fill. Give the filled shapes a temporary stroke, draw that outline, then fade the fill in. Quick and convincing for bold marks.
- Mask reveal. Draw a simple centerline path that traces the logo, with a stroke wide enough to cover it, inside a
<mask>. In a luminance mask, MDN's example notes "everything under a white pixel will be visible," so as the white stroke draws, the real filled logo appears under it. Your artwork is never changed. - Wipe. A
<clipPath>"restricts the region to which paint can be applied." Animate a rectangle inside it to wipe the logo in from one side. It is not a hand-drawn look, but it works for any artwork.
<svg viewBox="0 0 200 60" role="img" aria-label="Offscript">
<mask id="reveal">
<path class="draw" pathLength="1" stroke="white" stroke-width="14"
d="M10 45 C40 5, 70 5, 100 40 S160 75, 190 15" />
</mask>
<g mask="url(#reveal)">
<!-- your filled logo paths, unchanged -->
</g>
</svg>
The same .draw CSS from above animates the mask path. Draw the centerline in the order a pen would move, because that is the order the logo appears.
How do you export a logo from Figma or Illustrator for a draw animation?
Check what the export actually contains. Figma's help lists "Figma exports strokes as fills" among its SVG export notes, and says "SVG only supports center stroke," with a Simplify stroke setting for inside and outside strokes. Its Outline text option "converts any text layers into glyphs," which are filled shapes. Any of these can leave you with no stroke to animate.
- Open the SVG in a text editor. A drawable path has
strokeset andfill="none". A path with onlyfillis a shape; use the mask method. - Draw lines as center strokes for anything meant to be drawn, such as a signature or a monoline mark.
- Name layers. Figma's Include "id" attribute option adds ids based on layer names, which your CSS or script can target.
- Illustrator: the same check applies to its SVG export. If paths come out as filled outlines, rebuild the drawn parts as open paths with a stroke before exporting.
How do you draw a logo with several paths in sequence?
Delay each path so the drawing moves from one stroke to the next, the way a hand would.
- Same duration per path: with
pathLength="1", every path takes the same time whatever its length. Simple, but a short tick and a long swash finish together, so the short one looks slow. - Constant pen speed: measure each path with
getTotalLength()and make its duration proportional to its length, starting each when the previous one ends. - Overlap a little: starting the next stroke slightly before the last one finishes reads as more fluid than a strict queue.
- Finish with the fill: fade fills and colors in after the last stroke so the logo ends exactly as designed.
A reveal that plays once in a couple of seconds is well under WCAG 2.2.2's five-second threshold for automatic motion. A draw that loops forever is not, so give a loop a stop.
When should you use Lottie or Rive instead of SVG and CSS?
When the reveal has to run outside the browser, or do more than draw.
- Lottie: the Lottie supported-features table lists Trim Path (individually) as supported on Android, iOS and Web. Trim Path applied simultaneously is not supported by the iOS Core Animation renderer.
- Rive: Trim Path lets you "draw only a portion of the stroke on a vector shape," with Start, End and Offset, and a Sequential mode that draws paths one after another. A Rive file can then go on into a state machine: draw in, idle, react to hover.
Stay with SVG and CSS when the logo only appears on the web, the motion is a single draw, and you want zero dependencies. Switch when the same animation must ship in an iOS or Android app, or when it needs states. Comparisons: Lottie vs SVG and CSS animation and SVG to Rive.
Can you get a handwritten logo reveal without coding it?
Charmotion's Motion Studio splits a flat wordmark into its letters, so they can be written by a pen, rise from one baseline or drop in and bounce, as with the Offscript demo. The letters come from your file and are never swapped for a font. A launch animation comes as a .riv with code for web, SwiftUI, Android, Flutter and React Native, plus MP4 and transparent video. Concepts are free; building one starts at Starter ($9/month as of November 2026).
How to make an SVG logo draw itself
- Check the paths. Open the SVG and confirm the parts to draw are paths with a stroke and fill set to none.
- Normalize length. Add pathLength="1" to each path, or measure each one with getTotalLength().
- Hide the line. Set stroke-dasharray and stroke-dashoffset to the path length so the stroke starts hidden.
- Animate the offset. Animate stroke-dashoffset to 0 with fill mode forwards, staggering paths in drawing order.
- Handle filled artwork. For filled logos, put a thick white centerline stroke in a mask over the real shapes and animate that stroke.
- Respect reduced motion. Under prefers-reduced-motion, skip the animation and show the finished logo.
Frequently asked questions
Why does my SVG draw animation do nothing on my logo?
Usually the logo has no strokes. Exported logos, outlined text and many Figma exports are filled shapes, so animating stroke-dashoffset changes nothing visible. Open the SVG and look for stroke on the paths. If there is only fill, use the mask method or add a temporary outline stroke.
Do I need JavaScript for an SVG line animation?
No. Setting pathLength="1" on each path lets plain CSS use stroke-dasharray: 1 and animate stroke-dashoffset from 1 to 0. JavaScript helps when you want constant drawing speed across paths of different lengths, or to start the animation on scroll or click.
Will the draw animation work if the SVG is used in an img tag?
Only if the animation is inside the SVG file. MDN notes that browsers may disable JavaScript and block external stylesheets for SVG used as an image, so put the CSS in a style element inside the SVG, or use SMIL, and test in the browsers you support.
Sources
- stroke-dasharray, MDN Web Docs
- stroke-dashoffset, MDN Web Docs
- SVGGeometryElement: getTotalLength() method, MDN Web Docs
- pathLength, MDN Web Docs
- animation-fill-mode, MDN Web Docs
- <animate>, MDN Web Docs
- SVG as an image, MDN Web Docs
- <mask>, MDN Web Docs
- <clipPath>, MDN Web Docs
- Web Animations API, MDN Web Docs
- Intersection Observer API, MDN Web Docs
- prefers-reduced-motion, MDN Web Docs
- Understanding SC 2.2.2: Pause, Stop, Hide, W3C WAI
- How SVG line animation works, CSS-Tricks
- Export formats and settings for static designs, Figma Learn
- Lottie supported features, Airbnb on GitHub
- Trim Path, Rive docs