ambient_effects_container 0.2.0
ambient_effects_container: ^0.2.0 copied to clipboard
A reusable Flutter ambient background container with rain, snow, leaf, petal, and firefly effects.
ambient_effects_container #
ambient_effects_container is a generalized Flutter particle effects container focused on creating immersive environmental atmospheres and dynamic backgrounds.
It seamlessly wraps any Flutter Widget and takes over the rendering and memory scheduling of all underlying particles, providing an elegant and smooth dynamic background experience.
Previews #
| Rain | Snow |
|---|---|
![]() |
![]() |
| Leaf | Sakura |
|---|---|
![]() |
![]() |
Currently, the container includes a rich variety of high-quality built-in preset effects:
RainEffect: Smoothly falling rain streaksSnowEffect: Serene, drifting snowLeafEffect: Concrete falling leaves with flip animationsFireflyEffect: Gently wandering, faintly glowing fireflies illuminating the dark ✨PetalEffect: A powerful, generalized falling petal system! Switch between floral types simply by passing a differentPetalStyle. It currently featuressakura(cherry blossom),rose,white(pure white petals), and the newly added, breathtakingly romanticwisteria, fully equipped with geometrically varying petal slices and gradient mapping 🌺 (Note: If you preferred the previous syntax, we've still retained the standaloneSakuraEffectas a convenient shortcut)
It is a highly reusable, premium-grade particle background foundation. It achieves:
- Complete decoupling of the rendering layer from the business layer, ensuring zero interference with frontend interaction logic.
- Underlying implementation based on
CustomPainterand object pooling technology, avoiding garbage collection (GC) stutters caused by creating numerous objects per frame. - Support for seamless wrapping of both full-screen backgrounds and arbitrary local containers, intelligently scaling particle density according to the container's size.
Core Highlights #
AmbientEffectsContainer: A unified entry point to adapt to various effects with write-once simplicity.- Completely Decoupled
PetalSystem: I have entirely separated the physical movements (falling, rotating, swaying) from the static visuals (SVG paths, gradient layers, veins) of the petals. In the future, even if you want to add any custom floral pattern of your own, you only need to append a few lines ofPetalShapeSpecdata! It's incredibly light on performance and highly playable. PerformanceMode: Built-inlow/balanced/highpresets to seamlessly balance visual fidelity and device power consumption.EffectRenderStyle: Supportsflat,layered(dual-layer parallax), andcinematic(three-layer panoramic) spatial perspective management.- Dynamic Playback Control: Supports real-time pausing and resuming of the underlying rendering engine via the
enabledproperty based on page visibility, maximizing battery and performance savings.
Installation #
Add the following dependency to your project's pubspec.yaml:
dependencies:
ambient_effects_container: ^0.1.0
Quick Start #
1. Import the package #
import 'package:ambient_effects_container/ambient_effects_container.dart';
import 'package:flutter/material.dart';
2. Full-Screen Background #
This is the most typical use case, often used for app login screens, splash screens, or meditation guides.
(Note: If the foreground contains a Scaffold, be sure to set its background color to transparent (Colors.transparent), otherwise it will obscure the canvas effects behind it.)
class DemoPage extends StatelessWidget {
const DemoPage({super.key});
@override
Widget build(BuildContext context) {
return AmbientEffectsContainer(
effect: const RainEffect.medium(),
performanceMode: PerformanceMode.balanced,
renderStyle: EffectRenderStyle.layered,
backgroundColor: const Color(0xFF233545),
child: Scaffold(
backgroundColor: Colors.transparent,
body: const Center(
child: Text(
'Rain Scene',
style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.w700),
),
),
),
);
}
}
This snippet declares three core presentation aspects:
effect: Determines the actual physical effect to render.performanceMode: The permitted rendering budget for the animation (directly impacting the maximum number of particles on screen).renderStyle: Whether to introduce depth-of-field parallax to create spatial tension between the foreground and background.
3. Immersive Background for Local Cards #
The exceptional advantage of AmbientEffectsContainer lies in its ability to perfectly adapt to any localized small area. It actively detects the actual display area and scales down the total number of particles proportionally, ensuring there is no abrupt "crowded particle accumulation" due to a small card size.
AmbientEffectsContainer(
effect: const SnowEffect.light(),
performanceMode: PerformanceMode.low,
renderStyle: EffectRenderStyle.layered,
backgroundColor: const Color(0x14000000),
child: Container(
height: 220,
padding: const EdgeInsets.all(20),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
child: const Text('Snow Card', style: TextStyle(color: Colors.white, fontSize: 20)),
),
)
Advanced & Tuning Configurations #
Pausing or Freezing Animations #
If the page is switched to the background, covered by a heavy overlay, or the user turns on the device's "battery-saving mode," you can dynamically pass enabled: false. The container will immediately put the physics engine to sleep, avoiding extra battery drain.
AmbientEffectsContainer(
effect: const LeafEffect.medium(),
enabled: false, // The particle animation is gently frozen at this moment
child: const Placeholder(),
)
Understanding Intensity Levels #
Please note that preset tags like heavy or light do not merely superficially change the "on-screen quantity." To convey natural phenomena accurately (e.g., the difference between a blizzard and a light drizzle), when the intensity increases, presets often simultaneously increase the absolute falling speed and the wind resistance angle.
If you only wish to increase the "visual density" of particles covering the screen without the urgency of a torrential storm, you can explicitly hold back the speed parameter:
AmbientEffectsContainer(
effect: const SakuraEffect(
intensity: SakuraIntensity.heavy, // Enable the highest density preset
speed: 1.0, // Force override to normal speed (making it a slow but extremely dense romantic sakura snow)
),
child: const Placeholder(),
)
Mastering the "Firefly" Wander #
Unlike rain, snow, and petals that rely on gravity to fall, the brand new FireflyEffect is born to express suspension and vitality. I specifically discarded the gravity constraints for it, exposing two soul-striking properties:
wander: Controls the range of random horizontal and vertical wandering of the particles in the air.blinkSpeed: Controls the rhythm of the breathing, faintly flickering glow.
Simply pair it with a dark background, and you can effortlessly render a serene, vibrant, deeply immersive forest atmosphere in the dark.
Do I Need to Manually Lock particleCount? #
In most implementation flows, the engine automatically calculates the most elegant total particle capacity based on the following implicit rule:
Container Display Area × Performance Tier (PerformanceMode) × Environmental Intensity (Intensity).
It is recommended to manually override the particleCount property only in the following two specialized cases:
- Strict Multi-Platform Consistency Alignment: You do not want the visual proportion of quantities to change due to the different physical areas between tablet and smartphone versions.
- Extreme Testing Environments: For instance, you are writing a stress-test page that strictly requires exactly 2000 particles running in the scene.
Detailed Parameter Reference #
AmbientEffectsContainer #
Through the main constructor, you have comprehensive control over the scene architecture:
const AmbientEffectsContainer({
Key? key,
// Core
required AmbientEffectConfig effect, // Specific configuration of the effects engine
required Widget child, // The foreground UI tree to be nested
// Behavior and Boundaries
bool enabled = true, // Master switch for the rendering engine
Clip clipBehavior = Clip.hardEdge, // Trimming method for out-of-bounds container content
Alignment childAlignment = Alignment.center,
Color? backgroundColor, // Background color layered beneath the particles
// Strategy Presets
PerformanceMode performanceMode = PerformanceMode.balanced,
EffectRenderStyle renderStyle = EffectRenderStyle.flat,
})
EffectRenderStyle (Parallax Depth Style) #
flat: All particle objects share the same dimension of projection parameters. Best performance, light and clean visuals.layered: The engine automatically divides particles into foreground and background layers by a certain ratio. The background layer, pushed further away, will gradually shrink, feature slight translucence, and move more sluggishly—creating a classically authenticated depth of field ("far is small and slow").cinematic: Further separates into three thicknesses: front, mid, and background. It leverages dramatic depth and speed differentials to construct an immersive blockbuster atmosphere; highly recommended to try this in full-screen mode.
Example Project #
The repository includes a highly comprehensive interactive debugging project located in the example/ directory.
You can freely switch scenes within this example app, and even slide the value bars to observe real-time feedback on the physics system and frame rate.
cd example
flutter run
Extension Guide #
The underlying design of this project is highly decoupled. If you wish to customize a specific set of new objects for your business (e.g., fluttering merchant vouchers, New Year red envelopes, colorful confetti):
- Inherit and create a
[New]Effectto handle configuration data exposed to the page. - Create a
[New]ParticleStateto handle physical collisions, angular velocity updates, and lifespan decay. - Implement your exclusive rule-updating Engine and Canvas drawing core Painter.
- Mount them into the factory, and then assemble and use them anywhere just like standard modules.
License #
MIT



