flutter-animating-apps

Implements animated effects, transitions, and motion in a Flutter app. Use when adding visual feedback, shared element transitions, or physics-based animations.

INSTALLATION
npx skills add https://github.com/flutter/skills --skill flutter-animating-apps
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

Animation Strategies

Apply conditional logic to select the correct animation approach:

  • If animating simple property changes (size, color, opacity) without playback control: Use Implicit Animations (e.g., AnimatedContainer, AnimatedOpacity, TweenAnimationBuilder).
  • If requiring playback control (play, pause, reverse, loop) or coordinating multiple properties: Use Explicit Animations (e.g., AnimationController with AnimatedBuilder or AnimatedWidget).
  • If animating elements between two distinct routes: Use Hero Animations (Shared Element Transitions).
  • If modeling real-world motion (e.g., snapping back after a drag): Use Physics-Based Animations (e.g., SpringSimulation).
  • If animating a sequence of overlapping or delayed motions: Use Staggered Animations (multiple Tweens driven by a single AnimationController using Interval curves).

Workflows

Implementing Implicit Animations

Use this workflow for "fire-and-forget" state-driven animations.

  • Task Progress:
  • Identify the target properties to animate (e.g., width, color).
  • Replace the static widget (e.g., Container) with its animated counterpart (e.g., AnimatedContainer).
  • Define the duration property.
  • (Optional) Define the curve property for non-linear motion.
  • Trigger the animation by updating the properties inside a setState() call.
  • Run validator -> review UI for jank -> adjust duration/curve if necessary.

Implementing Explicit Animations

Use this workflow when you need granular control over the animation lifecycle.

  • Task Progress:
  • Add SingleTickerProviderStateMixin (or TickerProviderStateMixin for multiple controllers) to the State class.
  • Initialize an AnimationController in initState(), providing vsync: this and a duration.
  • Define a Tween and chain it to the controller using .animate().
  • Wrap the target UI in an AnimatedBuilder (preferred for complex trees) or subclass AnimatedWidget.
  • Pass the Animation object to the AnimatedBuilder's animation property.
  • Control playback using controller.forward(), controller.reverse(), or controller.repeat().
  • Call controller.dispose() in the dispose() method.
  • Run validator -> check for memory leaks -> ensure dispose() is called.

Implementing Hero Transitions

Use this workflow to fly a widget between two routes.

  • Task Progress:
  • Wrap the source widget in a Hero widget.
  • Assign a unique, data-driven tag to the source Hero.
  • Wrap the destination widget in a Hero widget.
  • Assign the exact same tag to the destination Hero.
  • Ensure the widget trees inside both Hero widgets are visually similar to prevent jarring jumps.
  • Trigger the transition by pushing the destination route via Navigator.

Implementing Physics-Based Animations

Use this workflow for gesture-driven, natural motion.

  • Task Progress:
  • Set up an AnimationController (do not set a fixed duration).
  • Capture gesture velocity using a GestureDetector (e.g., onPanEnd providing DragEndDetails).
  • Convert the pixel velocity to the coordinate space of the animating property.
  • Instantiate a SpringSimulation with mass, stiffness, damping, and the calculated velocity.
  • Drive the controller using controller.animateWith(simulation).

Examples

class StaggeredAnimationDemo extends StatefulWidget {

  @override

  State<StaggeredAnimationDemo> createState() => _StaggeredAnimationDemoState();

}

class _StaggeredAnimationDemoState extends State<StaggeredAnimationDemo> with SingleTickerProviderStateMixin {

  late AnimationController _controller;

  late Animation<double> _widthAnimation;

  late Animation<Color?> _colorAnimation;

  @override

  void initState() {

    super.initState();

    _controller = AnimationController(

      duration: const Duration(seconds: 2),

      vsync: this,

    );

    // Staggered width animation (0.0 to 0.5 interval)

    _widthAnimation = Tween<double>(begin: 50.0, end: 200.0).animate(

      CurvedAnimation(

        parent: _controller,

        curve: const Interval(0.0, 0.5, curve: Curves.easeIn),

      ),

    );

    // Staggered color animation (0.5 to 1.0 interval)

    _colorAnimation = ColorTween(begin: Colors.blue, end: Colors.red).animate(

      CurvedAnimation(

        parent: _controller,

        curve: const Interval(0.5, 1.0, curve: Curves.easeOut),

      ),

    );

    _controller.forward();

  }

  @override

  void dispose() {

    _controller.dispose(); // CRITICAL: Prevent memory leaks

    super.dispose();

  }

  @override

  Widget build(BuildContext context) {

    return AnimatedBuilder(

      animation: _controller,

      builder: (context, child) {

        return Container(

          width: _widthAnimation.value,

          height: 50.0,

          color: _colorAnimation.value,

        );

      },

    );

  }

}
Route createCustomRoute(Widget destination) {

  return PageRouteBuilder(

    pageBuilder: (context, animation, secondaryAnimation) => destination,

    transitionsBuilder: (context, animation, secondaryAnimation, child) {

      const begin = Offset(0.0, 1.0); // Start from bottom

      const end = Offset.zero;

      const curve = Curves.easeOut;

      final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

      final offsetAnimation = animation.drive(tween);

      return SlideTransition(

        position: offsetAnimation,

        child: child,

      );

    },

  );

}

// Usage: Navigator.of(context).push(createCustomRoute(const NextPage()));
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card