Enhaced m3 motion

This commit is contained in:
Marc Rejohn Castillano 2026-03-21 12:57:41 +08:00
parent 758869920c
commit b2c3202317

View File

@ -786,13 +786,11 @@ class _M3ErrorShakeState extends State<M3ErrorShake>
// 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<M3BounceIcon>
with TickerProviderStateMixin {
with SingleTickerProviderStateMixin {
late final AnimationController _entranceCtrl;
late final AnimationController _pulseCtrl;
late final Animation<double> _entrance;
late final Animation<double> _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<double>(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<M3BounceIcon>
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);
}
}