Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to prevent OneShotAnimation reset when the playback finishes? #205

Closed
TheFe91 opened this issue Feb 23, 2022 · 2 comments
Closed

How to prevent OneShotAnimation reset when the playback finishes? #205

TheFe91 opened this issue Feb 23, 2022 · 2 comments
Labels
bug Something isn't working

Comments

@TheFe91
Copy link

TheFe91 commented Feb 23, 2022

Description

I am using the Rive package in order to have some nice animations within my Flutter application and I have 2 doubts:

I have an animation where some docs gets animated. I want to play this animation on Tap of it, so I'm using OneShotAnimation. The play on tap works, however when the animation ends, it immediately gets reset to the first frame.
When I load the page, in addition, the animation is loaded from the last frame.
How to avoid those 2 problems?

Device & Versions

  • Device: Android Emulator, iPad 2019
  • OS: Android SDK API Level 30, iPadOS 15.3
Flutter 2.10.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision db747aa133 (2 weeks ago) • 2022-02-09 13:57:35 -0600
Engine • revision ab46186b24
Tools • Dart 2.16.1 • DevTools 2.9.2

Preview

My code
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';

class Square extends StatefulWidget {
  final Widget page;
  final String title;

  const Square({
    required this.page,
    required this.title,
    Key? key,
  }) : super(key: key);

  @override
  State<Square> createState() => _SquareState();
}

class _SquareState extends State<Square> {
  late RiveAnimationController _esamiController;
  bool _isPlaying = false;

  @override
  void initState() {
    _esamiController = OneShotAnimation(
      'Animation 1',
      autoplay: false,
      onStart: () => setState(() => _isPlaying = true),
      onStop: () => setState(() => _isPlaying = false),
    );
    super.initState();
  }

  @override
  void dispose() {
    _esamiController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () => _isPlaying ? null : _esamiController.isActive = true,
      child: SizedBox(
        width: 192,
        height: 192,
        child: Card(
          color: Colors.black26,
          elevation: 10,
          child: Center(
            child: RiveAnimation.asset(
              'assets/animations/esami.riv',
              controllers: [_esamiController],
              onInit: (_) => setState(() {}),
            ),
          ),
        ),
      ),
    );
  }
}
@TheFe91 TheFe91 added the bug Something isn't working label Feb 23, 2022
@zplata
Copy link
Contributor

zplata commented Mar 28, 2022

@TheFe91 Regarding the OneShotAnimation, we internally reset the animation at the end of its cycle. It sounds like you want it to pause on the last frame? There are 2 approaches for this that could work:

  1. You could use a state machine that when the animation state you want to play plays, it transitions into an idle animation of that last frame (which could be its own state) or whatever frame you want to show
  2. You could extend the OneShotAnimation controller to override the onActiveChanged method. https://pub.dev/documentation/rive/latest/rive/OneShotAnimation-class.html

In this method, that's where we call the reset method when the isActive property of the animation is set to false to reset to the first frame. See the line in our source here: https://github.com/rive-app/rive-flutter/blob/master/lib/src/controllers/one_shot_controller.dart#L34

What you can do is in your extended class (i.e OneShotCustomAnimation) you can override the method and remove the check below:

    if (!isActive) {
      reset();
    }

Then when you instantiate your controller, just use OneShotCustomAnimation instead of OneShotAnimation.

@HayesGordon
Copy link
Contributor

Closing this as it appears to have a satisfactory answer 😃

Please reopen if anyone has additional questions, or reach out on Discord.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants