FloatingElement¶
Oscillating float animation for dynamic elements
FloatingElement creates a natural floating effect by combining vertical oscillation with optional rotation, perfect for clouds, decorative elements, or attention-grabbing content.
Table of Contents¶
Overview¶
Create gently floating elements:
FloatingElement(
position: Offset(100, 200),
floatAmplitude: Offset(0, 10),
floatFrequency: 0.5,
child: Image.asset('cloud.png'),
)
The element oscillates using a sine wave for smooth, natural motion.
Properties¶
| Property | Type | Default | Description |
|---|---|---|---|
child |
Widget |
required | Widget to float |
position |
Offset |
Offset.zero |
Base position |
floatAmplitude |
Offset |
Offset(0, 10) |
Movement range (x, y) |
floatFrequency |
double |
0.5 |
Cycles per second |
floatPhase |
double |
0.0 |
Phase offset (0.0 - 1.0) |
rotation |
double |
0.0 |
Base rotation (radians) |
rotationAmplitude |
double |
0.0 |
Rotation oscillation (radians) |
showShadow |
bool |
false |
Show drop shadow |
shadowBlur |
double |
10 |
Shadow blur radius |
shadowOffset |
Offset |
Offset(0, 5) |
Shadow position |
shadowColor |
Color |
black 25% | Shadow color |
Constructors¶
Default Constructor¶
Full control:
FloatingElement(
child: MyWidget(),
position: Offset(100, 200),
floatAmplitude: Offset(5, 12),
floatFrequency: 0.4,
floatPhase: 0.0,
)
FloatingElement.withRotation¶
Adds gentle rotation oscillation:
FloatingElement.withRotation(
child: Image.asset('leaf.png'),
position: Offset(100, 200),
floatAmplitude: Offset(0, 8),
floatFrequency: 0.4,
rotationDegrees: 3.0, // Oscillate ±3 degrees
)
Examples¶
Basic Float¶
FloatingElement(
position: Offset(100, 200),
floatAmplitude: Offset(0, 15),
floatFrequency: 0.5,
child: Image.asset('assets/cloud.png'),
)
Horizontal Float¶
FloatingElement(
position: Offset(400, 300),
floatAmplitude: Offset(20, 0), // X movement only
floatFrequency: 0.3,
child: Icon(Icons.arrow_forward, size: 48),
)
Combined Movement¶
FloatingElement(
position: Offset(200, 200),
floatAmplitude: Offset(10, 15), // Both X and Y
floatFrequency: 0.4,
child: Icon(Icons.star, size: 48, color: Colors.yellow),
)
With Rotation¶
FloatingElement.withRotation(
position: Offset(300, 250),
floatAmplitude: Offset(5, 10),
floatFrequency: 0.35,
rotationDegrees: 5.0,
child: Image.asset('assets/balloon.png', width: 80),
)
Multiple Floating Elements¶
Create depth with different phases:
Scene(
durationInFrames: 300,
background: Background.solid(Color(0xFF87CEEB)),
children: [
// Background clouds (slow, small)
FloatingElement(
position: Offset(100, 80),
floatAmplitude: Offset(3, 8),
floatFrequency: 0.25,
floatPhase: 0.0,
child: Opacity(
opacity: 0.5,
child: Image.asset('assets/cloud.png', width: 150),
),
),
// Mid clouds
FloatingElement(
position: Offset(400, 120),
floatAmplitude: Offset(5, 10),
floatFrequency: 0.35,
floatPhase: 0.3,
child: Opacity(
opacity: 0.7,
child: Image.asset('assets/cloud.png', width: 180),
),
),
// Foreground clouds (faster, larger movement)
FloatingElement(
position: Offset(600, 60),
floatAmplitude: Offset(8, 12),
floatFrequency: 0.45,
floatPhase: 0.6,
child: Image.asset('assets/cloud.png', width: 200),
),
],
)
Floating Stars¶
Scene(
durationInFrames: 240,
background: Background.solid(Color(0xFF1a1a2e)),
children: [
// Main content
VCenter(child: MainContent()),
// Floating stars at different positions and phases
for (int i = 0; i < 10; i++)
FloatingElement(
position: Offset(
100.0 + (i * 150) % 800,
80.0 + (i * 70) % 400,
),
floatAmplitude: Offset(3 + (i % 4), 8 + (i % 5)),
floatFrequency: 0.3 + (i % 3) * 0.1,
floatPhase: i * 0.1,
child: Icon(
Icons.star,
size: 16.0 + (i % 3) * 8,
color: Colors.yellow.withOpacity(0.6 + (i % 4) * 0.1),
),
),
],
)
With Shadow¶
FloatingElement(
position: Offset(300, 200),
floatAmplitude: Offset(0, 12),
floatFrequency: 0.5,
showShadow: true,
shadowBlur: 15,
shadowOffset: Offset(0, 8),
shadowColor: Colors.black.withOpacity(0.3),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Icon(Icons.emoji_emotions, size: 50),
),
)
Floating Cards¶
Scene(
durationInFrames: 180,
children: [
FloatingElement(
position: Offset(100, 200),
floatAmplitude: Offset(5, 10),
floatFrequency: 0.4,
floatPhase: 0.0,
showShadow: true,
child: PhotoCard.simple(
assetPath: 'assets/photo1.jpg',
width: 200,
height: 150,
),
),
FloatingElement(
position: Offset(350, 180),
floatAmplitude: Offset(6, 12),
floatFrequency: 0.35,
floatPhase: 0.33,
showShadow: true,
child: PhotoCard.simple(
assetPath: 'assets/photo2.jpg',
width: 200,
height: 150,
),
),
FloatingElement(
position: Offset(600, 220),
floatAmplitude: Offset(4, 8),
floatFrequency: 0.45,
floatPhase: 0.66,
showShadow: true,
child: PhotoCard.simple(
assetPath: 'assets/photo3.jpg',
width: 200,
height: 150,
),
),
],
)
Floating with Rotation¶
FloatingElement.withRotation(
position: Offset(400, 300),
floatAmplitude: Offset(8, 15),
floatFrequency: 0.3,
rotationDegrees: 5.0,
showShadow: true,
child: Transform.rotate(
angle: -0.1, // Base tilt
child: PolaroidFrame(
size: Size(200, 230),
caption: 'Memories',
child: Image.asset('assets/memory.jpg', fit: BoxFit.cover),
),
),
)
How It Works¶
The float animation uses a sine wave for smooth, natural motion:
The floatPhase offsets when each element is in its cycle, preventing synchronized movement.
Performance¶
FloatingElement uses TimeConsumer which recalculates position each frame. For many floating elements:
- Keep
floatAmplitudevalues small - Use lower
floatFrequencyfor background elements - Consider using CSS transforms for large counts (not available in Fluvie)
Related¶
- PropAnimation.float() - Float as PropAnimation
- PropAnimation.pulse() - Pulsing scale
- TimeConsumer - Frame-based animation