rive-app / rive-flutter

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

Change animation speed #125

Closed felixwortmann closed 3 years ago

felixwortmann commented 3 years ago

Is it possible to change the animation speed? It might be possible using the controller etc. I think it should be possible to just provide a double in RiveAnimation.asset('path',speed: 2).

mjohnsullivan commented 3 years ago

It's possible, though currently you'll need to write a custom controller to manage that.

We just added the ability for you to pass controllers into RiveAnimation rather than just names.

mjohnsullivan commented 3 years ago

Here's a quick example on the current API:

/// Demonstrates how to create a custom controller to change the speed of an
/// animation

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Simple Animation'),
      ),
      body: Center(
        child: RiveAnimation.network(
          'https://cdn.rive.app/animations/vehicles.riv',
          fit: BoxFit.cover,
          animations: const ['idle'],
          controllers: [SpeedController('curves', speedMultiplier: 3)],
        ),
      ),
    );
  }
}

class SpeedController extends SimpleAnimation {
  final double speedMultiplier;

  /// Stops the animation on the next apply
  bool _stopOnNextApply = false;

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

  @override
  void apply(RuntimeArtboard artboard, double elapsedSeconds) {
    if (_stopOnNextApply || instance == null) {
      isActive = false;
    }

    instance!.animation.apply(instance!.time, coreContext: artboard, mix: mix);
    if (!instance!.advance(elapsedSeconds * speedMultiplier)) {
      _stopOnNextApply = true;
    }
  }

  @override
  void onActivate() => _stopOnNextApply = false;
}
mjohnsullivan commented 3 years ago

Here's a simplified example:

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Custom Controller'),
      ),
      body: Center(
        child: RiveAnimation.network(
          'https://cdn.rive.app/animations/vehicles.riv',
          fit: BoxFit.cover,
          animations: const ['idle'],
          controllers: [SpeedController('curves', speedMultiplier: 3)],
        ),
      ),
    );
  }
}

class SpeedController extends SimpleAnimation {
  final double speedMultiplier;

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

  @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);
  }
}
felixwortmann commented 3 years ago

It is still a big chunk of boilerplate. Will the "easy" way also be implemented?

felixwortmann commented 3 years ago

@mjohnsullivan also I just noticed, your solution only works for RiveAnimation.network().
RiveAnimation.asset() does not have a parameter controllers.

mjohnsullivan commented 3 years ago

We're trying to balance simplicity vs. adding in too many options to the high level widgets. If there's a demand for adjusting the speed of an animation, we're happy to add it in.

mjohnsullivan commented 3 years ago

Current master has controllers on RiveAnimation: https://github.com/rive-app/rive-flutter/blob/master/lib/src/widgets/rive_animation.dart

Are you not seeing it in the latest pub version? 0.7.18

felixwortmann commented 3 years ago

Ok, that got fixed yesterday

tantzygames commented 3 years ago

We're trying to balance simplicity vs. adding in too many options to the high level widgets. If there's a demand for adjusting the speed of an animation, we're happy to add it in.

I would like to set the position and speed of animations.