magic_animations
Beautiful, easy-to-use Flutter animations. A curated set of entrance, interactive, and GPU shader effects with a dead-simple API — use them as wrapper widgets or as chainable one-liners on any widget.
Text('Hello').fadeIn().slideUp(); // chainable sugar
FadeIn(child: Text('Hello')); // or explicit wrappers
Icon(Icons.star).glow(); // GPU-powered shader effect
Pure Dart, zero native code, cross-platform (iOS, Android, web, desktop). The shader effects run on the GPU via GLSL fragment shaders and gracefully fall back to the plain child where shaders are unavailable.
Features
| Category | Animations |
|---|---|
| Entrance | fadeIn · slideUp / slideDown / slideInLeft / slideInRight · scaleIn · blurIn · flipIn · printIn (unroll through a slot) · shimmer · CountUp (animated number) · Typewriter (animated text reveal) |
| Interactive | pressScale · bouncyTap · rippleTap · jiggle (optional haptics) |
| Shaders (GPU) | glow · liquid · gradientFlow · dissolve |
Every animation is available two ways: as a wrapper widget (FadeIn(...))
and as a chainable extension on Widget (myWidget.fadeIn()).
Every entrance animation also supports:
trigger: AnimateTrigger.onVisible— play the first time it scrolls into view, instead of the moment it's built.onStart/onComplete— callbacks so app code can react to an animation actually starting or finishing (chain a haptic, reveal the next step, navigate away).Stagger— cascade a list or grid of them in by position, instead of everything appearing at once.
Getting started
Add the dependency:
dependencies:
magic_animations: ^0.1.0
Then import it:
import 'package:magic_animations/magic_animations.dart';
Requires Flutter 3.44+ (the shader effects use Impeller's fragment-shader support).
Usage
Entrance animations
// Plays automatically when the widget first appears.
Text('Welcome').fadeIn();
Card(...).slideUp(delay: Duration(milliseconds: 150));
Avatar().scaleIn(curve: Curves.easeOutBack);
// "Print" content out through a slot — unrolls from an edge like a receipt.
// Works on any widget or whole screen.
receiptCard.printIn(showSlot: true); // rolls down from the top
statsPanel.printIn(from: RevealEdge.bottom); // rises up from the bottom
// Compose several effects — they run together.
ProfileCard().fadeIn().slideUp();
// Only play once it's actually on screen — e.g. a stat on a long page —
// and react when it finishes.
DashboardCard().fadeIn(
trigger: AnimateTrigger.onVisible,
onComplete: () => HapticFeedback.lightImpact(),
);
// Animated numbers and typed-out text, both entrance widgets like the rest.
CountUp(end: 12480, decimals: 0, trigger: AnimateTrigger.onVisible);
Typewriter(text: 'Welcome to the app!', cursor: '|');
Staggering a list
Wrap each item with its position — inside an itemBuilder, or a fixed list —
and every entrance widget or AnimateX method underneath cascades in
automatically, instead of all playing at once:
ListView.builder(
itemBuilder: (context, i) => Stagger(
index: i,
child: ListTile(title: Text(items[i])).slideUp(),
),
)
// Or for a fixed list of already-built widgets:
Column(children: Stagger.list([tileA, tileB, tileC]))
Interactive animations
MyButton().pressScale(haptics: true); // shrink-on-press
LikeIcon().bouncyTap(onTap: _like); // springy pop
ListTile(...).rippleTap(); // ripple from touch point
NotificationBell().jiggle(); // attention wiggle
Shader effects
Icon(Icons.star, size: 64).glow(color: Colors.amber);
Text('magic_animations', style: big).gradientFlow(); // living gradient text
Card(...).liquid(); // swirling background
Banner().dissolve(); // noisy reveal with burn edge
Manual control
Drive any entrance animation imperatively with an AnimateController:
final controller = AnimateController();
FadeIn(
controller: controller,
trigger: AnimateTrigger.manual, // don't auto-play
child: banner,
);
// later…
controller.play();
controller.reverse();
controller.reset();
Don't forget to dispose() the controller.
Customizing
Common knobs across animations: duration, curve, delay, trigger,
visibleFraction (for onVisible), onStart/onComplete, and per-effect
options (offset, begin scale, sigma blur, overshoot, colors, speed).
Sensible defaults live in AnimateDefaults.
Example
A full gallery app lives in example/ showing every animation with
live replay. Run it with:
cd example
flutter run
Roadmap
Planned for future versions: page/route transitions, a richer loading/skeleton set, and a shared timeline for precisely sequencing multiple effects on one element.
Additional information
Contributions and issues welcome. Licensed under the MIT License.
Libraries
- magic_animations
- magic_animations — beautiful, easy-to-use Flutter animations.