SVG Animations
Draw SVG strokes with DrawSVG and animate stroke and fill colors.
Animate SVG icons and illustrations by progressively revealing strokes with drawSVG, or by transitioning stroke and fill colors. These properties work on any SVG element with a stroke — <path>, <circle>, <line>, <polyline>, and so on.
DrawSVG
drawSVG progressively reveals or hides an SVG stroke by controlling where the visible portion starts and ends along the path. Pass it inside from or to.
import { Motion } from "@motion.page/sdk";
// Draw a stroke in from hidden to fully visible
Motion("draw-logo", "#logo path", {
from: { drawSVG: "0% 0%" },
to: { drawSVG: "0% 100%" },
duration: 1.5,
ease: "power2.inOut",
}).onPageLoad(); Because "0% 100%" (fully visible) is the natural drawn state, you can use from-only and let the SDK resolve the endpoint from the element’s current state:
// Simpler — from hidden, animate to natural (fully drawn) state
Motion("draw-logo", "#logo path", {
from: { drawSVG: "0% 0%" },
duration: 1.5,
ease: "power2.inOut",
}).onPageLoad(); DrawSVG Format
The drawSVG value defines a window along the stroke — two points (start and end) expressed as percentages or pixels.
| Value | Meaning |
|---|---|
"0% 100%" | Full stroke visible (natural state) |
"0% 0%" | Fully hidden — good draw-in start |
"100% 100%" | Fully hidden from the other end |
"20% 80%" | Middle portion only — edges hidden |
"50%" | Shorthand for "0% 50%" — first half visible |
"100px 500px" | Pixel range along the stroke |
// Reveal from the end (wipe-out effect)
Motion("wipe", ".icon path", {
from: { drawSVG: "100% 100%" },
to: { drawSVG: "0% 100%" },
duration: 0.8,
ease: "power2.out",
}).onScroll({ toggleActions: "play none none none" });
// Reveal middle portion
Motion("partial", "circle", {
from: { drawSVG: "0% 0%" },
to: { drawSVG: "20% 80%" },
duration: 1,
}).onPageLoad(); Object Format
Pass an object with start and end keys. Values are percentages 0–100 (not 0–1 fractions).
// Object format — same as "20% 80%"
Motion("draw-arc", "path", {
from: { drawSVG: { start: 0, end: 0 } },
to: { drawSVG: { start: 20, end: 80 } },
duration: 1.2,
ease: "power2.inOut",
}).onPageLoad(); Caution:
{ start: 0.2, end: 0.8 }is not20%–80%— these are percentages, so20and80are the correct values. Using0.2/0.8would give you 0.2%–0.8%, a nearly invisible sliver.
Stroke Color
stroke sets and animates the color of the line drawn around an SVG element. Pass any CSS color string.
// Animate stroke color on hover
Motion("stroke-hover", ".icon", {
to: { stroke: "#6633EE" },
duration: 0.3,
ease: "power2.out",
}).onHover({ each: true, onLeave: "reverse" }); // Transition stroke color on page load
Motion("stroke-in", "path", {
from: { stroke: "#cccccc" },
to: { stroke: "#ff4444" },
duration: 0.8,
}).onPageLoad(); Because stroke reads the element’s current CSS as the missing endpoint, from-only and to-only both work correctly.
Fill Color
fill animates the color painted inside an SVG shape. Same behavior as stroke — pass any CSS color string, and use from or to depending on whether the natural CSS is the start or end state.
// Fill a shape on scroll
Motion("fill-in", ".icon-shape", {
from: { fill: "transparent" },
to: { fill: "#6633EE" },
duration: 0.6,
ease: "power2.out",
}).onScroll({ toggleActions: "play none none none" }); // Hover color change
Motion("fill-hover", ".nav-icon path", {
to: { fill: "#0099ff" },
duration: 0.2,
}).onHover({ each: true, onLeave: "reverse" }); Combining DrawSVG and Color
drawSVG, stroke, and fill all work in the same animation config. Use a multi-step timeline to draw the stroke first, then fill the shape.
// Draw the stroke, then fill — sequential with position offset
Motion("draw-and-fill", "#logo", [
{
target: "#logo path",
from: { drawSVG: "0% 0%", stroke: "#aaaaaa" },
to: { drawSVG: "0% 100%", stroke: "#6633EE" },
duration: 1.5,
ease: "power2.inOut",
},
{
target: "#logo path",
from: { fill: "transparent" },
to: { fill: "#6633EE" },
duration: 0.6,
ease: "power2.out",
position: "+=0.1",
},
]).onPageLoad(); Or animate them in parallel within a single config:
// Draw and color-shift simultaneously
Motion("draw-color", "path", {
from: { drawSVG: "0% 0%", stroke: "#cccccc" },
to: { drawSVG: "0% 100%", stroke: "#6633EE" },
duration: 1.2,
ease: "power2.inOut",
}).onPageLoad(); Common Patterns
Logo Draw-In
Stagger multiple paths for a sequential logo reveal. Target all paths in the SVG and use stagger to offset each one.
Motion("logo-draw", "#logo path", {
from: { drawSVG: "0% 0%" },
duration: 1,
ease: "power2.inOut",
stagger: 0.15,
}).onPageLoad(); Icon Reveal on Scroll
Trigger the draw when the icon enters the viewport. Each icon animates independently with each: true.
Motion("icon-reveal", ".feature-icon path", {
from: { drawSVG: "0% 0%", opacity: 0 },
duration: 0.8,
ease: "power2.out",
stagger: 0.1,
}).onScroll({ each: true, toggleActions: "play none none none" }); Progress Indicator
Scrub drawSVG against scroll to show reading progress or step completion.
Motion("progress", "#progress-ring circle", {
from: { drawSVG: "0% 0%" },
to: { drawSVG: "0% 100%" },
duration: 1,
}).onScroll({
scrub: true,
start: "top top",
end: "bottom bottom",
}); Animated Underline on Hover
Draw a stroke underline from left to right on hover, reverse on leave.
Motion("underline", ".nav-link", {
from: { drawSVG: "0% 0%" },
to: { drawSVG: "0% 100%" },
duration: 0.35,
ease: "power2.out",
}).onHover({ each: true, onLeave: "reverse" }); Draw with Yoyo Loop
Loop a stroke drawing and erasing for a continuous loading or attention indicator.
Motion("loading-ring", ".spinner circle", {
from: { drawSVG: "0% 0%" },
to: { drawSVG: "0% 100%" },
duration: 1,
ease: "power1.inOut",
repeat: { times: -1, yoyo: true },
}).onPageLoad(); Tips
- SVG elements must have a
strokeCSS property set (either inline or via CSS) fordrawSVGto work — it manipulatesstroke-dasharrayandstroke-dashoffsetunder the hood. fill: "none"on a path means the interior is transparent. Animate from"none"to a color by settingfrom: { fill: "none" }explicitly.stroke-linecap: roundon the SVG element produces smoother draw-in effects at the start and end of strokes.- Use
transformOriginto control the center of rotation if you also rotate SVG elements during the draw animation.