agentsclimarketplace

Flutter animation

Skill ulpi-io/plugin-marketplace/plugins/flutter/skills/flutter-animation

A curated collection of 7,800+ agent skills for Claude Desktop, sourced from skills.sh

Install
npx -y skills add ulpi-io/plugin-marketplace --skill flutter-animation

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Add animated effects to your Flutter app

SKILL.md

7.6 KB, ~1.8k tokens by cl100k_base, as published. Nobody here has run it

Flutter Animations Implementation

Goal

Implements and manages Flutter animations, selecting the appropriate animation strategy (implicit, explicit, tween, physics, hero, or staggered) based on UI requirements. Assumes a working Flutter environment, stateful/stateless widget competence, and a standard widget tree structure.

Instructions

1. Determine Animation Strategy (Decision Logic)

Evaluate the UI requirement using the following decision tree to select the correct animation approach:

  1. Is the animation a simple property change (color, size, alignment) on a single widget?
    • YES: Use Implicit Animations (e.g., AnimatedContainer).
    • NO: Proceed to 2.
  2. Does the animation model real-world movement (springs, gravity, velocity)?
    • YES: Use Physics-based animation (SpringSimulation, animateWith).
    • NO: Proceed to 3.
  3. Does the animation involve a widget flying between two different screens/routes?
    • YES: Use Hero Animations (Hero widget).
    • NO: Proceed to 4.
  4. Does the animation involve multiple sequential or overlapping movements?
    • YES: Use Staggered Animations (Single AnimationController with multiple Tweens and Interval curves).
    • NO: Use Standard Explicit Animations (AnimationController, Tween, AnimatedBuilder / AnimatedWidget).

STOP AND ASK THE USER: If the requirement is ambiguous, pause and ask the user to clarify the desired visual effect before writing implementation code.

2. Implement Implicit Animations

For simple transitions between values, use implicit animation widgets. Do not manually manage state or controllers.

AnimatedContainer(
  duration: const Duration(milliseconds: 500),
  curve: Curves.bounceIn,
  width: _isExpanded ? 200.0 : 100.0,
  height: _isExpanded ? 200.0 : 100.0,
  decoration: BoxDecoration(
    color: _isExpanded ? Colors.green : Colors.blue,
    borderRadius: BorderRadius.circular(_isExpanded ? 50.0 : 8.0),
  ),
  child: const FlutterLogo(),
)

3. Implement Explicit Animations (Tween-based)

When you need to control the animation (play, pause, reverse), use an AnimationController with a Tween. Separate the transition rendering from the state using AnimatedBuilder.

class _MyAnimatedWidgetState extends State<MyAnimatedWidget> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    
    _animation = Tween<double>(begin: 0, end: 300).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeOut),
    )..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          _controller.reverse();
        } else if (status == AnimationStatus.dismissed) {
          _controller.forward();
        }
      });
      
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose(); // STRICT REQUIREMENT
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return SizedBox(
          height: _animation.value,
          width: _animation.value,
          child: child,
        );
      },
      child: const FlutterLogo(), // Passed as child for performance
    );
  }
}

4. Implement Page Route Transitions

To animate transitions between routes, use PageRouteBuilder and chain a CurveTween with a Tween<Offset>.

Route<void> _createRoute() {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => const DestinationPage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      const begin = Offset(0.0, 1.0);
      const end = Offset.zero;
      const curve = Curves.ease;

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

      return SlideTransition(
        position: animation.drive(tween),
        child: child,
      );
    },
  );
}

5. Implement Physics-Based Animations

For realistic motion (e.g., snapping back after a drag), calculate velocity and apply a SpringSimulation.

void _runSpringAnimation(Offset pixelsPerSecond, Size size, Alignment dragAlignment) {
  _animation = _controller.drive(
    AlignmentTween(begin: dragAlignment, end: Alignment.center),
  );

  final unitsPerSecondX = pixelsPerSecond.dx / size.width;
  final unitsPerSecondY = pixelsPerSecond.dy / size.height;
  final unitsPerSecond = Offset(unitsPerSecondX, unitsPerSecondY);
  final unitVelocity = unitsPerSecond.distance;

  const spring = SpringDescription(mass: 1, stiffness: 1, damping: 1);
  final simulation = SpringSimulation(spring, 0, 1, -unitVelocity);

  _controller.animateWith(simulation);
}

6. Implement Hero Animations (Shared Element)

To fly a widget between routes, wrap the identical widget tree in both routes with a Hero widget using the exact same tag.

// Source Route
Hero(
  tag: 'unique-photo-tag',
  child: Image.asset('photo.png', width: 100),
)

// Destination Route
Hero(
  tag: 'unique-photo-tag',
  child: Image.asset('photo.png', width: 300),
)

7. Implement Staggered Animations

For sequential or overlapping animations, use a single AnimationController and define multiple Tweens with Interval curves.

class StaggerAnimation extends StatelessWidget {
  StaggerAnimation({super.key, required this.controller}) :
    opacity = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(
        parent: controller,
        curve: const Interval(0.0, 0.100, curve: Curves.ease),
      ),
    ),
    width = Tween<double>(begin: 50.0, end: 150.0).animate(
      CurvedAnimation(
        parent: controller,
        curve: const Interval(0.125, 0.250, curve: Curves.ease),
      ),
    );

  final AnimationController controller;
  final Animation<double> opacity;
  final Animation<double> width;

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        return Opacity(
          opacity: opacity.value,
          child: Container(width: width.value, height: 50, color: Colors.blue),
        );
      },
    );
  }
}

8. Validate-and-Fix Loop

After generating animation code, verify the following:

  1. Does the State class use SingleTickerProviderStateMixin (or TickerProviderStateMixin for multiple controllers)?
  2. Is _controller.dispose() explicitly called in the dispose() method?
  3. If using AnimatedBuilder, is the static widget passed to the child parameter rather than rebuilt inside the builder function? If any of these are missing, fix the code immediately before presenting it to the user.

Constraints

  • Strict Disposal: You MUST include dispose() methods for all AnimationController instances to prevent memory leaks.
  • No URLs: Do not include external links or URLs in the output or comments.
  • Immutability: Treat Tween and Curve classes as stateless and immutable. Do not attempt to mutate them after instantiation.
  • Performance: Always use AnimatedBuilder or AnimatedWidget instead of calling setState() inside a controller's addListener when building complex widget trees.
  • Hero Tags: Hero tags MUST be identical and unique per route transition. Do not use generic tags like 'image' if multiple heroes exist.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.