NibMotion
A declarative, physics-based animation framework for Flutter — inspired by Framer Motion.
Live Demo · Documentation · pub.dev
Preview
App Demo
Why NibMotion?
Flutter animations require AnimationController boilerplate, tweens everywhere, and complex rebuild logic. NibMotion replaces that with a simple mental model:
Describe how your UI should look in different states — NibMotion handles the rest.
No controllers. No tweens. Just state.
Installation
flutter pub add nib_motion
import 'package:nib_motion/nib_motion.dart';
Quick Start
NibMotion(
initial: const NibAnim(opacity: 0, y: 20),
animate: const NibAnim(opacity: 1, y: 0),
child: const Text('Hello NibMotion'),
)
Features
| Category | Features |
|---|---|
| Core | Declarative API, physics-based springs, zero external dependencies |
| Gestures | whileTap, whileHover, whileDrag, whileFocus |
| Variants | State-driven UI with cascading parent → child propagation |
| Presence | Exit animations before unmount |
| Viewport | Scroll-triggered entrance animations |
| Layout | FLIP animations for reorder/resize |
| Motion Values | High-performance reactive values — no widget rebuilds |
| Keyframes | Multi-step animations with easing control |
| Text | Per-char/word/line — NibText, NibTypewriter, NibGradientText, NibTextReveal |
| Shaders | GPU effects — NibShimmer, NibDissolve |
| Presets | NibShake, NibBounce, NibPulse, NibFloat, NibFlip, NibRubberBand |
| Gestures+ | NibDraggable, NibPinch, NibSwipeDismiss |
| Timeline | NibTimeline, NibAnimationSequence for orchestration |
| Path | NibPathMotion, NibDrawPath |
| Scroll | NibParallax, NibScrollReveal |
| Debug | NibMotionDebugger, NibPerfOverlay |
| Accessibility | Automatic reduced-motion support |
Usage
Gesture Animations
NibMotion(
whileTap: const NibAnim(scale: 0.95),
whileHover: const NibAnim(scale: 1.05),
child: YourWidget(),
)
Variants (State System)
NibMotion(
variants: {
'open': NibAnim(y: 0, opacity: 1),
'closed': NibAnim(y: 20, opacity: 0),
},
initial: 'closed',
animate: isOpen ? 'open' : 'closed',
child: YourWidget(),
)
Keyframes
NibMotion(
keyframes: [
NibKeyframe(at: 0.0, value: NibAnim(opacity: 0, y: 30)),
NibKeyframe(at: 0.6, value: NibAnim(opacity: 1, y: -5)),
NibKeyframe(at: 1.0, value: NibAnim(opacity: 1, y: 0)),
],
child: YourWidget(),
)
Exit Animations (Presence)
NibPresence(
children: [
if (visible)
NibMotion(
key: const ValueKey('item'),
initial: const NibAnim(opacity: 0, y: 20),
animate: const NibAnim(opacity: 1, y: 0),
exit: const NibAnim(opacity: 0, y: 20),
child: YourWidget(),
),
],
)
Viewport Animations
NibMotion(
initial: const NibAnim(opacity: 0, y: 30),
whileInView: const NibAnim(opacity: 1, y: 0),
viewport: const NibInViewConfig(amount: 0.2),
child: YourWidget(),
)
Layout Animations (FLIP)
NibLayoutGroup(
children: tasks.map((t) => TaskCard(t)).toList(),
)
Spring Physics
NibMotion(
animate: const NibAnim(x: 100),
transition: NibTransition.spring(NibSpringDescription.snappy),
child: YourWidget(),
)
Scroll-Linked Motion
final scrollY = ScrollMotionBridge(controller: scrollController);
NibMotion(
animate: NibAnim(opacity: scrollY.mapRange([0, 200], [1, 0])),
child: YourWidget(),
)
Imperative Controller
final controller = NibMotionController();
NibMotion(
controller: controller,
child: YourWidget(),
);
await controller.animateTo(const NibAnim(scale: 1.2));
Reduced Motion
NibMotionConfig(
reducedMotion: true,
child: MyApp(),
)
Philosophy
NibMotion is built around one idea:
UI should be described, not animated manually.
It gives Flutter a motion model closer to modern UI frameworks like Framer Motion — but fully native, performant, and Flutter-optimized. Animating never triggers a widget rebuild — MotionValue notifications call markNeedsPaint directly on the render object.
License
MIT — see LICENSE.
Libraries
- nib_motion
- Declarative animation primitives for Flutter — Framer Motion-style physics-based animations with zero AnimationController boilerplate.