Home > Back-end >  How to toggle rive animation when tapped on the animation in flutter
How to toggle rive animation when tapped on the animation in flutter

Time:04-18

I am a beginner to rive and flutter. I am building a favorite items page in flutter. If there are not anything added to favorites I need to show a riveAnimation on screen. I already implemented almost everything to show the animation on screen. But I need to toggle a jumping animation when user tap on the animation which is really cool. for now I have the animation on 'Idle' mode

You may want to refer to the rive file => image

The code and the image may be little bit bigger. Sorry about that

class Favourites extends StatefulWidget {
  Favourites({Key? key}) : super(key: key);

  @override
  State<Favourites> createState() => _FavouritesState();
}

class _FavouritesState extends State<Favourites> {
  String animation = 'idle';
  SMIInput<String>? _birdInput;
  Artboard? _birdArtboard;

  void jump() {
    setState(() {
      _birdInput?.value = 'Pressed';
    });
  }

  @override
  void initState() {
    super.initState();
    rootBundle.load('assets/rive/bird.riv').then(
      (data) {
        final file = RiveFile.import(data);
        final artboard = file.mainArtboard;
        var controller = StateMachineController.fromArtboard(
          artboard,
          'Bird',
        );
        if (controller != null) {
          artboard.addController(controller);
          _birdInput = controller.findInput('Pressed');
        }
        setState(() => _birdArtboard = artboard);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    final favourite = Provider.of<Favourite>(context);
    return Scaffold(
      backgroundColor: Colors.grey[300],
      appBar: const CustomAppBar(title: 'Favourites'),
      body: favourite.items.isEmpty
          ? Center(
              child: Column(
                children: [
                  SizedBox(
                    width: 300,
                    height: 500,
                    child: _birdArtboard == null
                        ? const SizedBox()
                        : Center(
                            child: GestureDetector(
                              onTap: () {},
                              child: Rive(artboard: _birdArtboard!),
                            ),
                          ),
                  ),
                   NeumorphicButton(),
                ],
              ),
            )
          : CustomGrid(),
    );
  }
}

CodePudding user response:

If you open/run rive file on rive site, you can find that it is using Trigger variable for jumping and it is using State Machine 1 state machine.

enter image description here

Next thing comes about declaring variable. You need to use SMITrigger data type for this and use StateMachineController to control the animation.

Use .findSMI(..) instead of .findInput() for SMITrigger.

To start animation on trigger, use

 trigger?.fire();

I will encourage you to take a look on editor and check input variable type while performing rive animation.

So the full widget that will provide animation is

class Favourites extends StatefulWidget {
  const Favourites({Key? key}) : super(key: key);

  @override
  State<Favourites> createState() => _FavouritesState();
}

class _FavouritesState extends State<Favourites> {
  String animation = 'idle';

  Artboard? _birdArtboard;
  SMITrigger? trigger;
  StateMachineController? stateMachineController;

  @override
  void initState() {
    super.initState();
    rootBundle.load('assets/rive/bird.riv').then(
      (data) {
        final file = RiveFile.import(data);
        final artboard = file.mainArtboard;
        stateMachineController =
            StateMachineController.fromArtboard(artboard, "State Machine 1");
        if (stateMachineController != null) {
          artboard.addController(stateMachineController!);
          trigger = stateMachineController!.findSMI('Pressed');

          stateMachineController!.inputs.forEach((e) {
            debugPrint(e.runtimeType.toString());
            debugPrint("name${e.name}End");
          });
          trigger = stateMachineController!.inputs.first as SMITrigger;
        }

        setState(() => _birdArtboard = artboard);
      },
    );
  }

  void jump() {
    trigger?.fire();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.grey[300],
        body: Center(
          child: Column(
            children: [
              SizedBox(
                width: 300,
                height: 400,
                child: _birdArtboard == null
                    ? const SizedBox()
                    : Center(
                        child: GestureDetector(
                          onTap: () {
                            jump();
                          },
                          child: Rive(artboard: _birdArtboard!),
                        ),
                      ),
              ),
            ],
          ),
        ));
  }
}

enter image description here

  • Related