Path drawing example: Step-by-step
In this tutorial, we'll build the Path drawing example step-by-step.
This example is rated 2/5 difficulty, which means we'll spend some time explaining the Motion APIs we've chosen to use, but it assumes familiarity with JavaScript as a language.
Introduction
The Path Drawing example shows how to create a drawing animation effect using SVGs and Motion for React.
In this tutorial, we'll use the variants
and motion
component from Motion for React to create a staggered animation effect across multiple SVG elements.
Get started
Let's start by setting up our SVG container and shapes without animation:
import React from "react"
export default function PathDrawing() {
return (
<svg
width="600"
height="600"
viewBox="0 0 600 600"
style={{ maxWidth: "80vw" }}
>
<circle
cx="100"
cy="100"
r="80"
stroke="#FF0055"
style={{
strokeWidth: 10,
strokeLinecap: "round",
fill: "transparent",
}}
/>
<line
x1="220"
y1="30"
x2="360"
y2="170"
stroke="#7700FF"
style={{
strokeWidth: 10,
strokeLinecap: "round",
fill: "transparent",
}}
/>
{/* More shapes would go here */}
</svg>
)
}
This creates a basic SVG with circle, cross and square shapes.
Let's animate!
Now let's bring our SVG to life by adding animations.
Import from Motion
First, import the motion
component from Motion for React:
import { motion } from "motion/react"
Creating the animation variants
Next, we'll define how our paths should animate. We'll create variants that control the pathLength
property, which determines how much of the path is drawn (0
= none, 1
= all):
const draw = {
hidden: { pathLength: 0, opacity: 0 },
visible: (i: number) => {
const delay = i * 0.5
return {
pathLength: 1,
opacity: 1,
transition: {
pathLength: { delay, type: "spring", duration: 1.5, bounce: 0 },
opacity: { delay, duration: 0.01 },
},
}
},
}
Let's break down what's happening:
- The
hidden
state setspathLength: 0
(nothing drawn) andopacity: 0
(invisible). - The
visible
state is a function that accepts a custom index parameter (i
). We'll pass this in to eachmotion.path
via itscustom
prop. - The delay is calculated based on this index, creating a staggered effect.
Applying the animation
Now, let's convert our SVG elements to motion
components and apply our animation:
export default function PathDrawing() {
return (
<motion.svg
width="600"
height="600"
viewBox="0 0 600 600"
initial="hidden"
animate="visible"
style={{ maxWidth: "80vw" }}
>
<motion.circle
cx="100"
cy="100"
r="80"
stroke="#FF0055"
variants={draw}
custom={1}
style={{
strokeWidth: 10,
strokeLinecap: "round",
fill: "transparent",
}}
/>
<motion.line
x1="220"
y1="30"
x2="360"
y2="170"
stroke="#7700FF"
variants={draw}
custom={2}
style={{
strokeWidth: 10,
strokeLinecap: "round",
fill: "transparent",
}}
/>
{/* More shapes would go here */}
</motion.svg>
)
}
You can see each path
gets its own index
, which we use to calculate a staggered delay. The container switches the variant for all its children from "hidden"
to "visible"
.
Conclusion
In this tutorial, we learned how to:
- Animate SVG paths using the
pathLength
property - Create staggered animations using
variants
and thecustom
prop - Coordinate multiple animations to create a complex drawing effect
The pathLength
property is especially powerful for SVG animations, as it gives the appearance of drawing each shape stroke by stroke. Combined with Motion's animation capabilities, it creates visually appealing drawing effects that would be difficult to achieve with CSS alone.
This technique works with any SVG element that has a stroke, including circles, lines, rectangles, and complex paths. Try experimenting with different timing values, transition types, and SVG shapes to create your own unique drawing animations!
Tutorial Project
We're currently working on adding a tutorial for every example on the Motion Examples website. So far, 12% of examples have a tutorial.