DEV Community

Suhavi Sandhu
Suhavi Sandhu

Posted on

Flutter Web and Rive Animation Tutorial

Flutter Web and Rive Animation Tutoria

Hi! This is a beginner to intermediate tutorial for setting up a Flutter web app with Rive animations. I recently built a sliding tile game that incorporates Rive animations for the Flutter Hackathon. In this tutorial I’m going to show you how to add an animation to your Flutter web app and control it through user input.

We will create a basketball animation that gets triggered each time the user clicks on a button.

First we’ll create the animation. If you already have your animation you can skip to this section which will show you how to add your animation to a web app.

Rive is a free-to-use platform for designing and creating animations. We are going to use a basketball animation that Rive provides as one of their tutorials. Here is the animation.

When you open it, there’s a Design tab that let’s you modify the look of the animation, like the colours and original shape of the ball.

Rive Design Tab

If you switch to the Animate tab you can see the animation run. Each animation can have multiple ‘states’, in this one there’s an idle state but you could add more, like a rolling state or whatever you might need for your business logic.

Rive Animate Tab

Download the animation in the newest runtime as basketball.riv. Once we hook it up to Flutter, we will be able to play the idle animation when the user performs some action, such as clicking a button.

Create a flutter project that we will be adding the animation to. Once the project is created, make an assets folder if it doesn't already exist and move your animation file into it. I saved mine under assets/animations/.

flutter create fluttertutorial
cd fluttertutorial
flutter run -d chrome
Enter fullscreen mode Exit fullscreen mode

It will spin up a demo app for you that looks something like this.

Flutter Demo App

Next we add the library that is going to help us control (play and pause) our animation.

Add to pubspec.yaml and run flutter pub get.

dependencies:
    rive: ^0.8.4
Enter fullscreen mode Exit fullscreen mode

Then in lib/main.dart, import the package.

import 'package:rive/rive.dart';
Enter fullscreen mode Exit fullscreen mode

Now let’s add the animation to our app by creating a stateless widget. Add this code to the end of lib/main.dart

class BasketBallAnimation extends StatelessWidget {
  const BasketBallAnimation({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: RiveAnimation.asset('animations/basketball.riv')),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

To display this class, find the main class, MyApp and set home: to point to our new widget.

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const BasketBallAnimation(), // make this change
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Now when you re-run, you should see the basketball animation playing.

Stateless basketball animation

Now let’s give the widget state - this is how we will be able to tell if it’s playing or paused.

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

  @override
  State<BasketBallAnimation> createState() => _BasketBallAnimationState();
}

class _BasketBallAnimationState extends State<BasketBallAnimation> {
  bool isPlaying = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: const Center(child: RiveAnimation.asset('animations/basketball.riv')),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Next we will add a button that, when called, will change the value of isPlaying

class _BasketBallAnimationState extends State<BasketBallAnimation> {
  bool isPlaying = false;

    void _toggleAnimation() {
    setState(() {
      isPlaying = !isPlaying;
    });
  }

    @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:
          const Center(child: RiveAnimation.asset('animations/basketball.riv')),
            floatingActionButton: FloatingActionButton(
        onPressed: _toggleAnimation,
        tooltip: isPlaying ? 'Pause' : 'Play',
        child: Icon(
          isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
  }
}
Enter fullscreen mode Exit fullscreen mode

Finally, we can hook up the RiveController methods. The RiveAnimationController is what holds the state of our animation. Initially, we are going to set it to play our animation named idle. This is a SimpleAnimation. We will be able to tell if the animation is playing or not by checking the isActive property of the controller. We attach this controller to our animation asset by passing it into our animation.

RiveAnimation.asset('path/to/my/animation.riv', controllers: [_controller])
Enter fullscreen mode Exit fullscreen mode

Here is the updated code with the controller hooked up.

class _BasketBallAnimationState extends State<BasketBallAnimation> {
  late RiveAnimationController _controller;

  bool get isPlaying => _controller.isActive;

  void _toggleAnimation() {
    setState(() {
      _controller.isActive = !_controller.isActive;
    });
  }

  @override
  void initState() {
    super.initState();
    _controller = SimpleAnimation('idle');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: RiveAnimation.asset('animations/basketball.riv',
              controllers: [_controller])),
      floatingActionButton: FloatingActionButton(
        onPressed: _toggleAnimation,
        tooltip: isPlaying ? 'Pause' : 'Play',
        child: Icon(
          isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Now you should have something that looks like the screen below. A basketball animation that starts and stops when the user interacts with the floating button.

Final app with animation

Hope this tutorial helps you. The complete code for lib/main.dart can be found in this gist. Happy coding :)

Discussion (3)

Collapse
yourmdsarfaraj profile image
MD Sarfaraj

Thanks for sharing, I'm also thinking to build game in Flutter.
but I'm little bit confuse which game should I build.

Collapse
suhavi profile image
Suhavi Sandhu Author

Check the flutter hackathon project gallery for inspo! I played a few myself flutterhack.devpost.com/project-ga...

Collapse
yourmdsarfaraj profile image
MD Sarfaraj

Thank you looks some awesome game there