Fade

entrance

Opacity-based enter and exit. The simplest and most versatile animation.

Preview

Installation

Terminal
flutter pub add nib_motion

Usage

dart
NibMotion(
  initial: NibAnim(opacity: 0),
  animate: NibAnim(opacity: 1),
  exit:    NibAnim(opacity: 0),
  transition: const NibTransition(),
  child: MyWidget(),
)

Examples

Fade In

Opacity-only entrance. Simplest NibMotion animation — no transform involved.

dart
class FadeInExample extends StatefulWidget {
  const FadeInExample({super.key});

  @override
  State<FadeInExample> createState() => _FadeInExampleState();
}

class _FadeInExampleState extends State<FadeInExample> {
  final _signal = NibMotionReplaySignal();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            NibMotionReplayScope(
              signal: _signal,
              child: NibMotion(
                initial: const NibAnim(opacity: 0),
                animate: const NibAnim(opacity: 1),
                transition: const NibTransition(duration: Duration(milliseconds: 600)),
                child: Container(
                  width: 200,
                  height: 100,
                  decoration: BoxDecoration(
                    color: const Color(0xFF1C2537),
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: const Color(0xFF54C5F8).withAlpha(50)),
                  ),
                  child: const Center(
                    child: Text(
                      'Fade In',
                      style: TextStyle(
                        color: Color(0xFFEDF2F7),
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 24),
            TextButton.icon(
              onPressed: _signal.replay,
              icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
              label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
            ),
          ],
        ),
      ),
    );
  }
}

Slide Up

Pure Y-axis entrance with no opacity change. Card rises into place.

dart
class SlideUpExample extends StatefulWidget {
  const SlideUpExample({super.key});

  @override
  State<SlideUpExample> createState() => _SlideUpExampleState();
}

class _SlideUpExampleState extends State<SlideUpExample> {
  final _signal = NibMotionReplaySignal();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            NibMotionReplayScope(
              signal: _signal,
              child: NibMotion(
                initial: const NibAnim(y: 60, opacity: 0),
                animate: const NibAnim(y: 0, opacity: 1),
                transition: const NibTransition(
                  spring: NibSpringDescription.gentle,
                  duration: Duration(milliseconds: 650),
                ),
                child: Container(
                  width: 200,
                  height: 100,
                  decoration: BoxDecoration(
                    color: const Color(0xFF1C2537),
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: const Color(0xFF54C5F8).withAlpha(50)),
                  ),
                  child: const Center(
                    child: Text(
                      'Slide Up',
                      style: TextStyle(
                        color: Color(0xFFEDF2F7),
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 24),
            TextButton.icon(
              onPressed: _signal.replay,
              icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
              label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
            ),
          ],
        ),
      ),
    );
  }
}

Slide Horizontal

Slide in from the right using the X axis. Useful for drawer panels and side sheets.

dart
class SlideHorizontalExample extends StatefulWidget {
  const SlideHorizontalExample({super.key});

  @override
  State<SlideHorizontalExample> createState() => _SlideHorizontalExampleState();
}

class _SlideHorizontalExampleState extends State<SlideHorizontalExample> {
  final _signal = NibMotionReplaySignal();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            NibMotionReplayScope(
              signal: _signal,
              child: NibMotion(
                initial: const NibAnim(x: 110, opacity: 0),
                animate: const NibAnim(x: 0, opacity: 1),
                transition: const NibTransition(
                  spring: NibSpringDescription.snappy,
                  duration: Duration(milliseconds: 600),
                ),
                child: Container(
                  width: 200,
                  height: 100,
                  decoration: BoxDecoration(
                    color: const Color(0xFF1C2537),
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: const Color(0xFF54C5F8).withAlpha(50)),
                  ),
                  child: const Center(
                    child: Text(
                      'Slide In ←',
                      style: TextStyle(
                        color: Color(0xFFEDF2F7),
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 24),
            TextButton.icon(
              onPressed: _signal.replay,
              icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
              label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
            ),
          ],
        ),
      ),
    );
  }
}

Fade + Slide

Combined opacity and Y offset — the most common entrance pattern.

dart
class FadeWithSlideExample extends StatefulWidget {
  const FadeWithSlideExample({super.key});

  @override
  State<FadeWithSlideExample> createState() => _FadeWithSlideExampleState();
}

class _FadeWithSlideExampleState extends State<FadeWithSlideExample> {
  final _signal = NibMotionReplaySignal();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            NibMotionReplayScope(
              signal: _signal,
              child: NibMotion(
                initial: const NibAnim(opacity: 0, y: 24),
                animate: const NibAnim(opacity: 1, y: 0),
                transition: NibTransition.springGentle,
                child: Container(
                  width: 200,
                  height: 100,
                  decoration: BoxDecoration(
                    color: const Color(0xFF1C2537),
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: const Color(0xFF54C5F8).withAlpha(50)),
                  ),
                  child: const Center(
                    child: Text(
                      'Fade + Slide',
                      style: TextStyle(
                        color: Color(0xFFEDF2F7),
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 24),
            TextButton.icon(
              onPressed: _signal.replay,
              icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
              label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
            ),
          ],
        ),
      ),
    );
  }
}

API Reference

API class

NibMotion

API Properties

initialanimateexittransition