Animation
Timing controls - duration, delay, stagger, easing, repeat.
Five timing props control how the draw animation plays. All are optional with sensible defaults.
| Prop | Type | Default | Description |
|---|---|---|---|
duration | number | 0.55 | Seconds the draw takes per stroke |
delay | number | 0 | Seconds to wait before drawing starts |
stagger | number | 0.12 | Per-stroke delay increment (cascade) |
easing | string | "easeInOut" | Motion easing curve |
repeat | number | 0 | How many extra times to repeat — Infinity loops |
duration
How long each stroke takes to draw, in seconds.
0.15s0.55s (default)2.5s<Heart duration={0.15} />
<Heart />
<Heart duration={2.5} />delay
Wait this many seconds before drawing starts. Useful for sequencing several icons.
delay=0delay=0.5delay=1<Heart delay={0} />
<Heart delay={0.5} />
<Heart delay={1} />stagger
Per-stroke delay increment. Higher values draw strokes one after the other; 0 draws everything at once.
stagger=0stagger=0.12 (default)stagger=0.4<Sparkles stagger={0} />
<Sparkles />
<Sparkles stagger={0.4} />easing
Motion easing curve. Accepts named curves ("linear", "easeIn", "easeOut", "easeInOut", "circIn", etc.) or a cubic-bezier tuple.
"linear""easeIn""easeOut""easeInOut" (default)<Heart easing="linear" />
<Heart easing="easeIn" />
<Heart easing="easeOut" />
<Heart />For a cubic-bezier curve:
<Heart easing={[0.16, 1, 0.3, 1]} />repeat
How many times to repeat the animation after the first play. Infinity loops forever (great for loaders, status indicators).
repeat=0 (default)repeat=2repeat=Infinity, onLeave=snap<Heart />
<Heart repeat={2} />
<Settings repeat={Infinity} duration={1.2} onLeave="snap" />repeat=Infinity + hover
An infinite animation never "completes" — and the default onLeave is "complete", which means "let the animation finish naturally." Combined, that means a hover-triggered infinite loop keeps running forever after you un-hover.
Two ways to fix it:
- Make leave cancel with
onLeave="snap"(the demo above) — the loop stops when the cursor leaves. - Decouple from hover with
trigger="mount"— the icon loops continuously from page load, regardless of mouse.
Loading-spinner pattern
<Settings
trigger="mount"
repeat={Infinity}
duration={1.2}
easing="linear"
/>App-wide timing
Set defaults once via the <MotionIconConfig> provider so you don't repeat yourself:
<MotionIconConfig duration={0.3} stagger={0.05} easing="easeOut">
<App />
</MotionIconConfig>