rive-app / rive-flutter

Flutter runtime for Rive
https://rive.app
MIT License
1.21k stars 191 forks source link

Negative speed not working #302

Closed riccardocescon closed 1 year ago

riccardocescon commented 1 year ago

I have a custom controller that overrides appy like this:

@override
  void apply(RuntimeArtboard artboard, double elapsedSeconds) {
    if (instance == null || !instance!.keepGoing) {
      isActive = false;
    }
    instance!
      ..animation.apply(instance!.time, coreContext: artboard, mix: mix)
      ..advance(elapsedSeconds * speedMultiplier);
  }

thanks to #125

When i call the River widget and set the controller speed to a negative number such as: speedMultiplier: -1 the animation simply is freezed, same result of putting that value to 0. with other values such as 0.5, 1, 2 and other positive numbers it works perfectly

I am trying to reverse-animating a One-Shot animation

Device & Versions (please complete the following information)

HayesGordon commented 1 year ago

Hi @riccardocescon, the editor recently got a new feature to control the speed of animations directly from there, you can also reverse animations. See this tweet: https://twitter.com/rive_app/status/1635765458807984128

I encourage you to make use of state machines instead of mixing animations directly with code when possible.

But for your instance where you want to reverse a one shot animation, the reason you're not seeing anything is because a one shot animation does not loop. So when you try to reverse from the start of the animation it won't do anything because the timeline can't "subtract" the elapsed time back to the end of the timeline (if that makes sense).

TLDR; what you'll need to do is first set the One Shot animation's timeline to the end, and then you can reverse it. Here is some sample code:

class ReverseController extends SimpleAnimation {
  final double speedMultiplier;

  ReverseController(
    String animationName, {
    double mix = 1,
    this.speedMultiplier = -1,
  }) : super(animationName, mix: mix);

  @override
  bool init(RuntimeArtboard artboard) {
    final success = super.init(artboard);
    if (success) {
      instance!.advance(instance!.animation.endTime);
      instance!.animation.speed = speedMultiplier;
    }
    return success;
  }
}