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

Provide a way to subscribe to the rive animation ticker #303

Open
lesnitsky opened this issue Mar 22, 2023 · 3 comments
Open

Provide a way to subscribe to the rive animation ticker #303

lesnitsky opened this issue Mar 22, 2023 · 3 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@lesnitsky
Copy link

It's easy enough to extend a simple animation controller so that it could be listened to and the outside world would know that the new frame was rendered, but this is not the case for StateMachineController. Check out this example. I had to rely on a source file directly and reimplement StateMachineController and partially copy the implementation, there's no other way to subscribe to the animation ticker (at least I didn't find one).

Would it be possible to make all animation controllers (including state machine) listenable?

I want to make this implementation cleaner.
Here's what it looks like:

dynamic_app_icon.mov
@lesnitsky lesnitsky added the bug Something isn't working label Mar 22, 2023
@HayesGordon
Copy link
Contributor

Hey @lesnitsky

I tried to recreate something myself without looking at your code, and I basically got to the same result. Adding it here for transparency.

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late StateMachineController controller;

  void onInit(Artboard artboard) {
    controller = StateMachineOnTickController.fromArtboard(
      artboard,
      'State Machine 1',
      onTick: () {
        print('tick');
      },
    )!;
    artboard.addController(controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RiveAnimation.asset(
        'assets/rotate-speed.riv',
        onInit: onInit,
      ),
    );
  }
}

class StateMachineOnTickController extends StateMachineController {
  StateMachineOnTickController(
    super.stateMachine, {
    core.OnStateChange? onStateChange,
    this.onTick,
  });

  final VoidCallback? onTick;

  static StateMachineController? fromArtboard(
    Artboard artboard,
    String stateMachineName, {
    core.OnStateChange? onStateChange,
    VoidCallback? onTick,
  }) {
    for (final animation in artboard.animations) {
      if (animation is StateMachine && animation.name == stateMachineName) {
        return StateMachineOnTickController(
          animation,
          onStateChange: onStateChange,
          onTick: onTick,
        );
      }
    }
    return null;
  }

  /// Override this to be notified on each animation frame.
  @override
  void apply(CoreContext core, double elapsedSeconds) {
    onTick?.call();
    super.apply(core, elapsedSeconds);
  }
}

How you're extending the State Machine Controller is completely fine.

It'll be simple enough for us to extend the API with a callback such as the one above if needed. Maybe then also supplying additional information, such as the elapsedSeconds. To make them listenable could have an impact on performance. We could potentially expose ListenableControllers alongside the regular ones - so that people can opt in to using them

@HayesGordon
Copy link
Contributor

I neglected to add that the above requires src imports:

import 'package:rive/src/core/core.dart';
import 'package:rive/src/rive_core/state_machine_controller.dart' as core;

@HayesGordon
Copy link
Contributor

Or alternatively we can create a Mixin, similar to AnimationLocalListenersMixin. Which is how Flutter's AnimationContoller works when calling addListener

@HayesGordon HayesGordon added the enhancement New feature or request label Aug 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants