StaggerConfig¶
Configuration for staggered child animations
StaggerConfig defines how children in VColumn and VRow should animate in sequence, with configurable delays between each child's animation start.
Table of Contents¶
Overview¶
Stagger animations create a cascading reveal effect where each child starts animating after a delay:
VColumn(
stagger: StaggerConfig(
delay: 10,
duration: 30,
),
children: [
Text('Item 1'), // Starts at frame 0
Text('Item 2'), // Starts at frame 10
Text('Item 3'), // Starts at frame 20
Text('Item 4'), // Starts at frame 30
],
)
Animation Timeline¶
Frame: 0 10 20 30 40 50 60 70
| | | | | | | |
Item 1: ███████████████████████████████
Item 2: ███████████████████████████████
Item 3: ███████████████████████████████
Item 4: ███████████████████████████████
↑ ↑ ↑ ↑
delay between each start
Properties¶
| Property | Type | Default | Description |
|---|---|---|---|
delay |
int |
required | Frames between each child's start |
duration |
int? |
null |
Animation duration (default: 20) |
curve |
Curve |
Curves.easeOut |
Easing curve |
fadeIn |
bool |
true |
Enable fade animation |
slideIn |
bool |
false |
Enable slide animation |
slideOffset |
Offset |
Offset(0, 30) |
Slide start offset |
scaleIn |
bool |
false |
Enable scale animation |
scaleStart |
double |
0.8 |
Starting scale value |
Factory Constructors¶
Basic Constructor¶
Full control over all properties:
StaggerConfig(
delay: 10,
duration: 30,
curve: Curves.easeOut,
fadeIn: true,
slideIn: true,
slideOffset: Offset(0, 40),
scaleIn: false,
scaleStart: 0.8,
)
StaggerConfig.fade¶
Simple fade-in only:
StaggerConfig.slideUp¶
Slide up from below with fade:
StaggerConfig.slideUp(
delay: 10,
duration: 30,
distance: 40, // Pixels to slide
curve: Curves.easeOut,
)
StaggerConfig.slideDown¶
Slide down from above with fade:
StaggerConfig.slideLeft¶
Slide from the right with fade:
StaggerConfig.slideRight¶
Slide from the left with fade:
StaggerConfig.scale¶
Scale up with fade:
StaggerConfig.scale(
delay: 10,
duration: 30,
start: 0.7, // Starting scale
curve: Curves.easeOut,
)
StaggerConfig.slideUpScale¶
Combined slide up + scale + fade:
StaggerConfig.slideUpScale(
delay: 12,
duration: 35,
slideDistance: 30,
scaleStart: 0.85,
curve: Curves.easeOut,
)
Helper Methods¶
effectiveDuration¶
Returns the actual duration (default 20 if not specified):
startFrameForIndex¶
Calculates when a specific child starts:
final stagger = StaggerConfig(delay: 10);
print(stagger.startFrameForIndex(0)); // 0
print(stagger.startFrameForIndex(1)); // 10
print(stagger.startFrameForIndex(2)); // 20
// With base frame offset
print(stagger.startFrameForIndex(0, 30)); // 30
print(stagger.startFrameForIndex(1, 30)); // 40
endFrameForIndex¶
Calculates when a specific child's animation ends:
final stagger = StaggerConfig(delay: 10, duration: 25);
print(stagger.endFrameForIndex(0)); // 25
print(stagger.endFrameForIndex(1)); // 35
print(stagger.endFrameForIndex(2)); // 45
totalDuration¶
Calculates the total time for all children to finish:
final stagger = StaggerConfig(delay: 10, duration: 30);
// 3 children: last starts at frame 20, ends at frame 50
print(stagger.totalDuration(3)); // 50
// 5 children: last starts at frame 40, ends at frame 70
print(stagger.totalDuration(5)); // 70
Examples¶
Basic Staggered List¶
Scene(
durationInFrames: 150,
background: Background.solid(Colors.black),
children: [
VPadding(
padding: EdgeInsets.all(60),
startFrame: 0,
child: VColumn(
spacing: 20,
stagger: StaggerConfig.slideUp(
delay: 10,
duration: 30,
distance: 40,
),
children: [
Text('First item', style: TextStyle(fontSize: 24, color: Colors.white)),
Text('Second item', style: TextStyle(fontSize: 24, color: Colors.white)),
Text('Third item', style: TextStyle(fontSize: 24, color: Colors.white)),
Text('Fourth item', style: TextStyle(fontSize: 24, color: Colors.white)),
],
),
),
],
)
Staggered Row¶
VRow(
spacing: 20,
stagger: StaggerConfig.scale(
delay: 8,
duration: 25,
start: 0.5,
),
children: [
Icon(Icons.star, size: 48, color: Colors.yellow),
Icon(Icons.star, size: 48, color: Colors.yellow),
Icon(Icons.star, size: 48, color: Colors.yellow),
Icon(Icons.star, size: 48, color: Colors.yellow),
Icon(Icons.star, size: 48, color: Colors.yellow),
],
)
Ranking List¶
VColumn(
spacing: 16,
stagger: StaggerConfig.slideRight(
delay: 12,
duration: 30,
distance: 100,
),
children: [
_buildRankItem(1, 'Pop Hits', '2,450 streams'),
_buildRankItem(2, 'Rock Classics', '1,890 streams'),
_buildRankItem(3, 'Jazz Vibes', '1,234 streams'),
_buildRankItem(4, 'Electronic', '987 streams'),
_buildRankItem(5, 'Classical', '654 streams'),
],
)
Grid with Stagger¶
Column(
children: [
// First row
VRow(
stagger: StaggerConfig.scale(delay: 5, duration: 20),
children: [card1, card2, card3],
),
SizedBox(height: 20),
// Second row (starts after first row)
VRow(
stagger: StaggerConfig.scale(
delay: 5,
duration: 20,
).copyWith(startFrame: 30), // Offset start
children: [card4, card5, card6],
),
],
)
Fast Reveal¶
Quick succession for dynamic feel:
VColumn(
stagger: StaggerConfig.fade(
delay: 3, // Very short delay
duration: 15, // Quick animation
),
children: statsWidgets,
)
Slow Dramatic Reveal¶
Slower pacing for emphasis:
VColumn(
stagger: StaggerConfig.slideUpScale(
delay: 25, // Long delay between items
duration: 45, // Slow animation
slideDistance: 60,
scaleStart: 0.6,
),
children: importantItems,
)
Custom Combined Effect¶
VColumn(
stagger: StaggerConfig(
delay: 15,
duration: 35,
curve: Easing.easeOutBack, // Bounce effect
fadeIn: true,
slideIn: true,
slideOffset: Offset(0, 50),
scaleIn: true,
scaleStart: 0.7,
),
children: featureCards,
)
Calculating Scene Length¶
Use totalDuration to size your scene:
final items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];
final stagger = StaggerConfig.slideUp(delay: 15, duration: 30);
// Calculate minimum scene length
final animationLength = stagger.totalDuration(items.length);
final holdTime = 60; // Time to hold after animations complete
final sceneLength = animationLength + holdTime;
Scene(
durationInFrames: sceneLength, // 90 + 60 = 150 frames
children: [
VColumn(
stagger: stagger,
children: items.map((item) => Text(item)).toList(),
),
],
)
Different Curves¶
// Snappy entrance
StaggerConfig.slideUp(
delay: 8,
curve: Easing.easeOutExpo,
)
// Bouncy entrance
StaggerConfig.scale(
delay: 10,
curve: Easing.easeOutBack,
)
// Smooth entrance
StaggerConfig.fade(
delay: 12,
curve: Easing.easeInOutCubic,
)
Timing Visualization¶
For a stagger with delay: 10 and duration: 30:
Child Start End Timeline
───── ───── ─── ────────────────────────────────────
0 0 30 ████████████████████████████████
1 10 40 ████████████████████████████████
2 20 50 ████████████████████████████████
3 30 60 ████████████████████████████████
4 40 70 ████████████████████████████████
Frame: 0 10 20 30 40 50 60 70
Total duration = startFrame(4) + duration = 40 + 30 = 70 frames
Related¶
- VColumn - Vertical layout with stagger
- VRow - Horizontal layout with stagger
- PropAnimation - Animation base class
- Easing - Animation curves