diff --git a/packages/smooth_app/assets/animations/nutriscore.riv b/packages/smooth_app/assets/animations/nutriscore.riv new file mode 100644 index 000000000000..8ac9e8b4caf1 Binary files /dev/null and b/packages/smooth_app/assets/animations/nutriscore.riv differ diff --git a/packages/smooth_app/lib/resources/app_animations.dart b/packages/smooth_app/lib/resources/app_animations.dart index 66240a0aa94e..69a8468fc3a1 100644 --- a/packages/smooth_app/lib/resources/app_animations.dart +++ b/packages/smooth_app/lib/resources/app_animations.dart @@ -6,6 +6,7 @@ import 'package:smooth_app/services/smooth_services.dart'; import 'package:smooth_app/themes/theme_provider.dart'; /// Widget to inject in the hierarchy to have a single instance of the RiveFile +/// (assets/animations/off.riv) class AnimationsLoader extends StatefulWidget { const AnimationsLoader({ required this.child, @@ -340,3 +341,96 @@ class _TorchAnimationState extends State { super.dispose(); } } + +class NutriScoreAnimation extends StatefulWidget { + const NutriScoreAnimation({ + this.size, + super.key, + }) : level = -1; + + const NutriScoreAnimation.A({ + this.size, + super.key, + }) : level = 0; + + const NutriScoreAnimation.B({ + this.size, + super.key, + }) : level = 1; + + const NutriScoreAnimation.C({ + this.size, + super.key, + }) : level = 2; + + const NutriScoreAnimation.D({ + this.size, + super.key, + }) : level = 3; + + const NutriScoreAnimation.E({ + this.size, + super.key, + }) : level = 4; + + final int level; + final double? size; + + @override + State createState() => _NutriScoreAnimationState(); +} + +class _NutriScoreAnimationState extends State { + StateMachineController? _controller; + + @override + void didUpdateWidget(covariant NutriScoreAnimation oldWidget) { + super.didUpdateWidget(oldWidget); + _changeNutriScoreState(widget.level); + } + + /// -1 is the initial value (= no NutriScore) + /// 0 : NutriScore A + /// 1 : NutriScore B + /// 2 : NutriScore C + /// 3 : NutriScore D + /// 4 : NutriScore E + /// You can test it here [https://rive.app/s/aSxao_1Mwkixud5Z2GbA5A/] + void _changeNutriScoreState(int nutriScoreValue) { + assert(nutriScoreValue >= -1 && nutriScoreValue <= 4); + final SMINumber currentValue = + _controller!.findInput('value')! as SMINumber; + if (currentValue.value != nutriScoreValue) { + currentValue.value = nutriScoreValue.toDouble(); + } + } + + @override + Widget build(BuildContext context) { + final double size = widget.size ?? IconTheme.of(context).size ?? 24.0; + + return SizedBox.square( + dimension: size, + child: RiveAnimation.asset( + 'assets/animations/nutriscore.riv', + artboard: 'Nutriscore', + fit: BoxFit.cover, + onInit: (Artboard artboard) { + _controller = StateMachineController.fromArtboard( + artboard, + 'Nutriscore', + ); + + artboard.addController(_controller!); + _changeNutriScoreState(widget.level); + }, + ), + ); + } + + @override + void dispose() { + _controller?.dispose(); + super.dispose(); + } +}