withDelay
The withDelay modifier adds a pause before an animation starts. Perfect for creating staggered animations, sequential reveals, and timed sequences where you need precise control over when animations begin.
Why Use withDelay?
Delay is essential for:
- Staggered animations - Reveal items one after another
- Sequential reveals - Guide users through content
- Timed sequences - Coordinate multiple animations
- Pacing control - Add breathing room between animations
Basic Syntax
withDelay(ms, animation)
Parameters
- ms (required): Delay time in milliseconds
- animation (required): The animation descriptor to run after the delay
Simple Example
Add a delay before an animation:
import { useValue, withDelay, withSpring, animate } from 'react-ui-animate';
function MyComponent() {
const [x, setX] = useValue(0);
const animateWithDelay = () => {
setX(withDelay(500, withSpring(200)));
};
return (
<>
<button onClick={animateWithDelay}>Animate (with 500ms delay)</button>
<animate.div
style={{
translateX: x,
width: 100,
height: 100,
background: '#60a5fa',
}}
/>
</>
);
}
Real-World Examples
Example 1: Staggered List Items
Reveal items one by one:
function StaggeredList({ items }) {
const [heights, setHeights] = useValue(items.map(() => 0));
const reveal = () => {
setHeights(withSequence(
items.map((_, i) =>
withDelay(i * 100, withSpring(100))
)
));
};
return (
<>
<button onClick={reveal}>Reveal Items</button>
{items.map((item, i) => (
<animate.div
key={item.id}
style={{
height: heights[i],
background: '#60a5fa',
marginBottom: 10,
padding: 10,
}}
>
{item.name}
</animate.div>
))}
</>
);
}
Example 2: Sequential Card Reveal
Cards appear one after another:
function CardGrid({ cards }) {
const [opacities, setOpacities] = useValue(cards.map(() => 0));
useEffect(() => {
setOpacities(withSequence(
cards.map((_, i) =>
withDelay(i * 150, withTiming(1, { duration: 400 }))
)
));
}, []);
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20 }}>
{cards.map((card, i) => (
<animate.div
key={card.id}
style={{
opacity: opacities[i],
translateY: (1 - opacities[i]) * 20,
background: 'white',
padding: 20,
borderRadius: 8,
}}
>
{card.title}
</animate.div>
))}
</div>
);
}
Example 3: Notification with Delay
Show notification, wait, then hide:
function DelayedNotification({ message, isVisible }) {
const [opacity, setOpacity] = useValue(0);
useEffect(() => {
if (isVisible) {
setOpacity(withSequence([
// Show immediately
withTiming(1, { duration: 300 }),
// Wait 3 seconds
withDelay(3000),
// Hide
withTiming(0, { duration: 300 }),
]));
}
}, [isVisible]);
return (
<animate.div
style={{
opacity,
position: 'fixed',
bottom: 20,
right: 20,
background: '#333',
color: 'white',
padding: '12px 24px',
borderRadius: 8,
}}
>
{message}
</animate.div>
);
}
Example 4: Multi-Step Animation
Chain animations with delays:
function MultiStepAnimation() {
const [style, setStyle] = useValue({
x: 0,
y: 0,
scale: 1,
});
const animate = () => {
setStyle(withSequence([
// Step 1: Move right (immediate)
withSpring({ x: 100 }),
// Step 2: Wait, then move down
withDelay(500, withSpring({ y: 100 })),
// Step 3: Wait, then scale up
withDelay(500, withSpring({ scale: 1.5 })),
// Step 4: Wait, then return
withDelay(1000, withSpring({ x: 0, y: 0, scale: 1 })),
]));
};
return (
<>
<button onClick={animate}>Animate</button>
<animate.div
style={{
translateX: style.x,
translateY: style.y,
scale: style.scale,
width: 100,
height: 100,
background: '#60a5fa',
}}
/>
</>
);
}
Using in Sequences
withDelay is commonly used within withSequence:
setX(withSequence([
withSpring(100),
withDelay(500), // Pause for 500ms
withTiming(200, { duration: 300 }),
withDelay(1000), // Pause for 1 second
withSpring(0),
]));
Common Patterns
Pattern 1: Staggered Reveal
const [opacities, setOpacities] = useValue([0, 0, 0, 0]);
const reveal = () => {
setOpacities(withSequence([
withDelay(0, withTiming([1, 0, 0, 0])),
withDelay(100, withTiming([1, 1, 0, 0])),
withDelay(200, withTiming([1, 1, 1, 0])),
withDelay(300, withTiming([1, 1, 1, 1])),
]));
};
Pattern 2: Sequential Actions
const [step, setStep] = useValue(0);
const executeSteps = () => {
setStep(withSequence([
withTiming(1), // Step 1
withDelay(500),
withTiming(2), // Step 2
withDelay(500),
withTiming(3), // Step 3
]));
};
Pattern 3: Typing Effect
const [text, setText] = useValue('');
const typeText = (fullText) => {
const sequence = fullText.split('').map((_, i) =>
withDelay(i * 50, () => {
setText(fullText.slice(0, i + 1));
})
);
// Execute sequence
};
Best Practices
✅ Do
- Use delays for staggered animations (100-200ms between items)
- Use delays in sequences for pacing
- Keep delays reasonable (50-500ms for most cases)
- Use delays to create breathing room between animations