diff --git a/lib/theme/m3_motion.dart b/lib/theme/m3_motion.dart index 23331ff8..0df3f0c7 100644 --- a/lib/theme/m3_motion.dart +++ b/lib/theme/m3_motion.dart @@ -786,13 +786,11 @@ class _M3ErrorShakeState extends State // M3BounceIcon — entrance + idle pulse for empty/error states // ═══════════════════════════════════════════════════════════════ -/// Displays an [icon] inside a colored circular badge with: -/// 1. A spring-bounce entrance animation on first build. -/// 2. A slow, gentle idle pulse (scale 1.0 → 1.06 → 1.0) that repeats -/// indefinitely to draw attention without being distracting. +/// Displays an [icon] inside a colored circular badge with a spring-bounce +/// entrance animation: scales from 0 → 1.0 with a slight overshoot. /// -/// Respects [m3ReducedMotion] — both animations are skipped when reduced -/// motion is enabled. +/// Respects [m3ReducedMotion] — the animation is skipped when reduced +/// motion is enabled, showing the badge immediately. class M3BounceIcon extends StatefulWidget { const M3BounceIcon({ super.key, @@ -814,36 +812,22 @@ class M3BounceIcon extends StatefulWidget { } class _M3BounceIconState extends State - with TickerProviderStateMixin { + with SingleTickerProviderStateMixin { late final AnimationController _entranceCtrl; - late final AnimationController _pulseCtrl; late final Animation _entrance; - late final Animation _pulse; @override void initState() { super.initState(); - - // Entrance: scale 0 → 1.0 with spring overshoot. + // One-shot spring entrance: scale 0 → 1.0 with natural overshoot. _entranceCtrl = AnimationController(vsync: this, duration: M3Motion.long); _entrance = CurvedAnimation(parent: _entranceCtrl, curve: M3Motion.spring); - - // Idle pulse: 1.0 → 1.06 → 1.0, repeating every 2.5 s. - _pulseCtrl = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 2500), - )..repeat(reverse: true); - _pulse = Tween(begin: 1.0, end: 1.06).animate( - CurvedAnimation(parent: _pulseCtrl, curve: Curves.easeInOut), - ); - _entranceCtrl.forward(); } @override void dispose() { _entranceCtrl.dispose(); - _pulseCtrl.dispose(); super.dispose(); } @@ -861,15 +845,7 @@ class _M3BounceIconState extends State if (m3ReducedMotion(context)) return badge; - return ScaleTransition( - scale: _entrance, - child: AnimatedBuilder( - animation: _pulse, - builder: (_, child) => - Transform.scale(scale: _pulse.value, child: child), - child: badge, - ), - ); + return ScaleTransition(scale: _entrance, child: badge); } }