Flutter animations
Skill almasumdev/awesome-flutter-agent-skills/.github/skills/ui/flutter-animations
Build smooth, 120Hz-friendly Flutter animations — implicit, explicit, Hero, and physics-based — without jank. Use this when adding motion, transitions, or micro-interactions.From its SKILL.md
npx -y skills add almasumdev/awesome-flutter-agent-skills --skill flutter-animationsAssembled 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.
SKILL.md
4.3 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it
Flutter Animations
Instructions
Animations give Flutter apps their identity, but done wrong they are the #1 source of jank. Pick the lowest-power tool that fits.
1. The Ladder (pick the simplest)
- Implicit —
AnimatedContainer,AnimatedOpacity,AnimatedAlign,AnimatedPositioned,AnimatedDefaultTextStyle. Change a field, Flutter tweens it. Use for state-driven tweaks. - Tween shortcuts —
TweenAnimationBuilder<T>when no widget-level implicit exists. - Explicit —
AnimationController+Tween+AnimatedBuilder/FadeTransition/SlideTransition. Use for coordinated or repeating animations. - Hero —
Hero(tag: ...)for shared-element transitions across routes. - Physics —
SpringSimulation,FrictionSimulationviaAnimationController.animateWithfor natural motion.
2. AnimationController Lifecycle
class _FadeInState extends State<FadeIn> with SingleTickerProviderStateMixin {
late final _ctrl = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
)..forward();
@override
void dispose() { _ctrl.dispose(); super.dispose(); }
@override
Widget build(BuildContext context) =>
FadeTransition(opacity: _ctrl, child: widget.child);
}
- Always
dispose()the controller. - Use
SingleTickerProviderStateMixinfor one controller,TickerProviderStateMixinfor multiple. - For controllers driven by Riverpod, create them in a
Notifierwithref.onDispose(ctrl.dispose).
3. Transitions — Use the Built-Ins
Prefer FadeTransition, SlideTransition, ScaleTransition, RotationTransition, SizeTransition over AnimatedBuilder — they are RepaintBoundary-aware and rebuild minimal subtrees.
4. Curves Matter
Curves.easeOutCubicfor UI elements entering.Curves.easeInCubicfor leaving.Curves.easeInOutCubicfor state changes.- Avoid
Curves.linear— feels robotic. - Clamp durations to 150–400ms for UI feedback; longer only for storytelling.
5. 120Hz / ProMotion
- Enable
ImpellerEnabled(default on iOS, opt-in on Android) for consistent frame pacing. - Use
SchedulerBinding.instance.addPostFrameCallbackfor layout-dependent animations. - Avoid
Opacityon animating subtrees — it forces an offscreen layer. UseFadeTransition(usesRenderAnimatedOpacity). - Avoid animating
ClipRRect,ShaderMask, orBackdropFilter— expensive on the raster thread.
6. Staggered Animations
Use Interval(start, end, curve: ...) on a single controller to stagger children, instead of multiple controllers.
final fadeIn = CurvedAnimation(parent: _ctrl, curve: const Interval(0.0, 0.5, curve: Curves.easeOut));
final slideIn = CurvedAnimation(parent: _ctrl, curve: const Interval(0.3, 1.0, curve: Curves.easeOutCubic));
7. Lottie, Rive, and Native Feel
- Rive (
rivepackage) — state-machine-driven vector animations, GPU-efficient, designer-friendly. Preferred for complex illustrations. - Lottie (
lottiepackage) — legacy JSON animations; fine for static loops, heavier than Rive. - For native-style page transitions, use
PageTransitionsThemewith platform-specific builders.
8. Hero Pitfalls
- Both source and destination
Heromust share the exact sametag. - The child should be the same type (or wrap both in an identical
Materialancestor) to avoid mid-flight rebuilds. - Use
flightShuttleBuilderto customize the in-flight widget (e.g., cross-fade).
9. Testing Animations
- Use
tester.pump(const Duration(milliseconds: 150))— do NOTpumpAndSettlefor infinite animations (it hangs). - Assert the controller value at intermediate points.
- For golden tests of mid-flight frames, pin a specific
animation.valueand capture.
10. Checklist
- Every
AnimationControlleris disposed. - Used the simplest option on the ladder (implicit → explicit → physics).
- No
Opacity/Clip*/BackdropFilteron animating hot subtrees. - Duration 150–400ms for UI feedback, curves are eased.
- Hero tags unique per screen pair; tested both directions.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.