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.