animator

Enables you to create stunning flutter animations, faster, efficient and with less code.

Null safety:

For null safety please use flutter_animator: ^3.1.0, without null safety: flutter_animator: 2.1.0

Flutter 3:

For flutter>=3 please use flutter_animator: ^3.2.2

Partly inspired by the amazing Animate.css package by Dan Eden. Please note, although it's inspired by Animate.css, this still is a Flutter package, meaning it will be available for all flutter-supported platforms.

Features:

  • Combine and chain Tweens with multiple easing-curves.
  • Less boilerplate code by using a widget which directly handles the controller, animations etc.
  • Automatically (re)starts animations on hot-reload after saving.
  • Animate your project with ease using the Animate.css based Widgets.

Please press the like button if you like this package, or star it on github.

Getting Started

Note: To see all of the animated widgets in action be sure to run the app in the demo_app package, or view them on the Animate.css page.

Put the dependency inside your pubspec.yml and run packages get.

Using one of the Animate.css style widgets:

import 'package:flutter/widgets.dart';
import 'package:flutter_animator/flutter_animator.dart';

class TestAnimatedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RubberBand(
      child: Text(
        'Rubber',
        style: TextStyle(fontSize: 20),
      ),
    );
  }
}

Please note that you can use the magnitude property in the AnimationPreferences to control the magnitude of the animations.

Using a GlobalKey to enable play/stop/reverse animations from code:

import 'package:flutter/widgets.dart';
import 'package:flutter_animator/flutter_animator.dart';

class TestAnimatedWidget extends StatefulWidget {
  @override
  _TestAnimatedWidgetState createState() => _TestAnimatedWidgetState();
}
class _TestAnimatedWidgetState extends State<TestAnimatedWidget> {
  //Register a key in your state:
  GlobalKey<AnimatorWidgetState> _key = GlobalKey<AnimatorWidgetState>();
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(
            //Render the widget using the _key
            child: RubberBand(
              key: _key,
              child: Text(
                'Rubber',
                style: TextStyle(fontSize: 60),
              ),
            ),
        ),
        Padding(
            padding: EdgeInsets.fromLTRB(10, 10, 10, 30),
            child: IconButton(
              icon: Icon(
                Icons.play_arrow,
                color: Colors.green,
              ),
              //Use _key.currentState to forward/stop/reverse
              onPressed: () => _key.currentState.forward(),
            ),
        ),
      ],
    );
  }
}

Create your own:

Below is the code (with extra comments) from the actual FadeInDown animated widget. It should give you a clear insight on how to animate with the Animator using the AnimatorWidget.

import 'package:flutter/widgets.dart';

import '../../flutter_animator.dart';

///Firstly, we create an _AnimationDefinition_.
///This is the actual animation part, which gets driven by the _AnimatorWidget_.
class FadeInDownAnimation extends AnimationDefinition {
  FadeInDownAnimation({
  ///[AnimationPreferences] allows us to use the animation with different parameters for:
  ///offset, duration, autoPlay and an animationStatusListener.
    AnimationPreferences preferences = const AnimationPreferences(),
  }) : super(
          preferences: preferences,
          ///If you want to use the size of the widget, you need to define it here. (needsScreenSize is also available)
          needsWidgetSize: true,
          ///The opacity to use on the first render when using screenSize or widgetSize.
          ///In some cases 'flickering' may appear when this isn't set to 1.0 or 0.0 respectively.
          preRenderOpacity: 0.0,
        );

  ///Use the build function to actually render the animated values.
  ///Performance-wise it's better to use a FadeTransition for opacity animation.
  ///Use AnimatedBuilder to update te animation and it's values.
  @override
  Widget build(BuildContext context, Animator animator, Widget child) {
    return FadeTransition(
      ///Use animator.get([KEY]) to get to the Animation object.
      opacity: animator.get("opacity"),
      child: AnimatedBuilder(
        ///[Animator] exposes the AnimationController via animator.controller.
        animation: animator.controller,
        child: child,
        builder: (BuildContext context, Widget child) => Transform.translate(
          child: child,
          ///Use animator.get([KEY]).value to get the animated value.
          offset: Offset(0.0, animator.get("translateY").value),
        ),
      ),
    );
  }

  ///Inside the getDefinition method we return the actual animation.
  @override
  Map<String, TweenList> getDefinition({Size screenSize, Size widgetSize}) {
    return {
      ///Define a [KEY] and a list of Animated values from 0 to 100 percent.
      ///Please not that you can also define an animation curve inside the [TweenPercentage] class:
      ///TweenPercentage(percent: 0, value: 0.0, curve: Curves.ease),
      "opacity": TweenList<double>(
        [
          TweenPercentage(percent: 0, value: 0.0),
          TweenPercentage(percent: 100, value: 1.0),
        ],
      ),
      "translateY": TweenList<double>(
        [
          TweenPercentage(percent: 0, value: -widgetSize.height),
          TweenPercentage(percent: 100, value: 0.0),
        ],
      ),
    };
  }
}

///To use the AnimationDefinition we just created we could do the following:
///For a single animation:
/// AnimatorWidget(child: [child], definition: FadeInDownAnimation());
/// 
///For In & Out Animations:
///  InOutAnimation(child: [child), inDefinition: FadeInDownAnimation(), outDefinition: ...);
/// 

Available default animations:

Attention Seekers

Attention Seekers

  • Bounce
  • Flash
  • HeadShake
  • HeartBeat
  • Jello
  • Pulse
  • RubberBand
  • Shake
  • Swing
  • Tada
  • Wobble

Bouncing Entrances

Bouncing Entrances

  • BounceIn
  • BounceInDown
  • BounceInLeft
  • BounceInRight
  • BounceInUp

Bouncing Exits

Bouncing Exits

  • BounceOut
  • BounceOutDown
  • BounceOutLeft
  • BounceOutRight
  • BounceOutUp

Fading Entrances

Fading Entrances

  • FadeIn
  • FadeInDown
  • FadeInDownBig
  • FadeInLeft
  • FadeInLeftBig
  • FadeInRight
  • FadeInRightBig
  • FadeInUp
  • FadeInUpBig

Fading Exits

Fading Exits

  • FadeOut
  • FadeOutDown
  • FadeOutDownBig
  • FadeOutLeft
  • FadeOutLeftBig
  • FadeOutRight
  • FadeOutRightBig
  • FadeOutUp
  • FadeOutUpBig

Flippers

Flippers

  • Flip
  • FlipInX
  • FlipInY
  • FlipOutX
  • FlipOutY

Lightspeed

Lightspeed

  • LightSpeedIn
  • LightSpeedOut

Rotating Entrances

Rotating Entrances

  • RotateIn
  • RotateInDownLeft
  • RotateInDownRight
  • RotateInUpLeft
  • RotateInUpRight

Rotating Exits

Rotating Exits

  • RotateOut
  • RotateOutDownLeft
  • RotateOutDownRight
  • RotateOutUpLeft
  • RotateOutUpRight

Sliding Entrances

Sliding Entrances

  • SlideInDown
  • SlideInLeft
  • SlideInRight
  • SlideInUp

Sliding Exits

Sliding Exits

  • SlideOutDown
  • SlideOutLeft
  • SlideOutRight
  • SlideOutUp

Slit Entrances

Sliding Entrances

  • SlitInDiagonal
  • SlitInHorizontal
  • SlitInVertical

Slit Exits

Sliding Exits

  • SlitOutDiagonal
  • SlitOutHorizontal
  • SlitOutVertical

Specials

Specials

  • CrossFadeAB (*not in preview)
  • Hinge
  • JackInTheBox
  • RollIn
  • RollOut

Zooming Entrances

Zooming Entrances

  • ZoomIn
  • ZoomInDown
  • ZoomInLeft
  • ZoomInRight
  • ZoomInUp

Zooming Exits

Zooming Exits

  • ZoomOut
  • ZoomOutDown
  • ZoomOutLeft
  • ZoomOutRight
  • ZoomOutUp

Libraries

animation/animation_definition
animation/animation_preferences
animation/animator
animation/animator_play_states
animation/tween_list
animation/tween_percentage
flutter_animator
utils/force_unwrap
utils/math
utils/pair
utils/perspective
utils/string_case_formatter
widgets/animator_widget
widgets/attention_seekers/bounce
widgets/attention_seekers/flash
widgets/attention_seekers/head_shake
widgets/attention_seekers/heart_beat
widgets/attention_seekers/jello
widgets/attention_seekers/pulse
widgets/attention_seekers/rubber_band
widgets/attention_seekers/shake
widgets/attention_seekers/swing
widgets/attention_seekers/tada
widgets/attention_seekers/wobble
widgets/bouncing_entrances/bounce_in
widgets/bouncing_entrances/bounce_in_down
widgets/bouncing_entrances/bounce_in_left
widgets/bouncing_entrances/bounce_in_right
widgets/bouncing_entrances/bounce_in_up
widgets/bouncing_exits/bounce_out
widgets/bouncing_exits/bounce_out_down
widgets/bouncing_exits/bounce_out_left
widgets/bouncing_exits/bounce_out_right
widgets/bouncing_exits/bounce_out_up
widgets/fading_entrances/fade_in
widgets/fading_entrances/fade_in_down
widgets/fading_entrances/fade_in_down_big
widgets/fading_entrances/fade_in_left
widgets/fading_entrances/fade_in_left_big
widgets/fading_entrances/fade_in_right
widgets/fading_entrances/fade_in_right_big
widgets/fading_entrances/fade_in_up
widgets/fading_entrances/fade_in_up_big
widgets/fading_exits/fade_out
widgets/fading_exits/fade_out_down
widgets/fading_exits/fade_out_down_big
widgets/fading_exits/fade_out_left
widgets/fading_exits/fade_out_left_big
widgets/fading_exits/fade_out_right
widgets/fading_exits/fade_out_right_big
widgets/fading_exits/fade_out_up
widgets/fading_exits/fade_out_up_big
widgets/flippers/flip
widgets/flippers/flip_in_x
widgets/flippers/flip_in_y
widgets/flippers/flip_out_x
widgets/flippers/flip_out_y
widgets/in_out_animation
widgets/light_speed/light_speed_in
widgets/light_speed/light_speed_out
widgets/rotating_entrances/rotate_in
widgets/rotating_entrances/rotate_in_down_left
widgets/rotating_entrances/rotate_in_down_right
widgets/rotating_entrances/rotate_in_up_left
widgets/rotating_entrances/rotate_in_up_right
widgets/rotating_exits/rotate_out
widgets/rotating_exits/rotate_out_down_left
widgets/rotating_exits/rotate_out_down_right
widgets/rotating_exits/rotate_out_up_left
widgets/rotating_exits/rotate_out_up_right
widgets/sliding_entrances/slide_in_down
widgets/sliding_entrances/slide_in_left
widgets/sliding_entrances/slide_in_right
widgets/sliding_entrances/slide_in_up
widgets/sliding_exits/slide_out_down
widgets/sliding_exits/slide_out_left
widgets/sliding_exits/slide_out_right
widgets/sliding_exits/slide_out_up
widgets/slit_entrances/slit_in_diagonal
widgets/slit_entrances/slit_in_horizontal
widgets/slit_entrances/slit_in_vertical
widgets/slit_exits/slit_out_diagonal
widgets/slit_exits/slit_out_horizontal
widgets/slit_exits/slit_out_vertical
widgets/specials/cross_fade_a_b
widgets/specials/hinge
widgets/specials/jack_in_the_box
widgets/specials/roll_in
widgets/specials/roll_out
widgets/zooming_entrances/zoom_in
widgets/zooming_entrances/zoom_in_down
widgets/zooming_entrances/zoom_in_left
widgets/zooming_entrances/zoom_in_right
widgets/zooming_entrances/zoom_in_up
widgets/zooming_exits/zoom_out
widgets/zooming_exits/zoom_out_down
widgets/zooming_exits/zoom_out_left
widgets/zooming_exits/zoom_out_right
widgets/zooming_exits/zoom_out_up