mirror of
https://github.com/rive-app/rive-flutter.git
synced 2025-08-06 08:29:35 +08:00

The goal of this PR is to improve the usability of events for the Flutter runtime and to hide unnecessary editor implementation detail. This also ensures that an event is not modifiable after it has been reported (from the runtime's perspective) This is achieved by exposing runtime specific classes `RiveEvent`, `RiveOpenURLEvent` and `RiveGeneralEvent` (similar to the other runtimes), and mapping the current `Event` to these classes as an immutable object. It also maps the list of events to a Map called `properties`. This PR also: - Adds more event examples and fixes the audio example (`.stop` resulted in issues, and calling dispose, etc.) - Adds tests for events TODO: - Will need to potentially change things (and expose the `delay`) when this lands: https://github.com/rive-app/rive/pull/5951 Diffs= eae01824d feat: expose wrapper event class to runtime (#5956) Co-authored-by: Gordon <pggordonhayes@gmail.com>
83 lines
2.1 KiB
Dart
83 lines
2.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:rive/rive.dart';
|
|
import 'package:just_audio/just_audio.dart';
|
|
|
|
/// An example demonstrating a simple state machine.
|
|
///
|
|
/// The "bumpy" state machine will be activated on tap of the vehicle.
|
|
class EventSounds extends StatefulWidget {
|
|
const EventSounds({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<EventSounds> createState() => _EventSoundsState();
|
|
}
|
|
|
|
class _EventSoundsState extends State<EventSounds> {
|
|
final _audioPlayer = AudioPlayer();
|
|
late final StateMachineController _controller;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_audioPlayer.setAsset('assets/step.mp3');
|
|
}
|
|
|
|
Future<void> _onRiveInit(Artboard artboard) async {
|
|
_controller =
|
|
StateMachineController.fromArtboard(artboard, 'skill-controller')!;
|
|
artboard.addController(_controller);
|
|
_controller.addEventListener(onRiveEvent);
|
|
}
|
|
|
|
void onRiveEvent(RiveEvent event) {
|
|
// Seconds since the event was triggered and it being reported.
|
|
// This can be used to scrub the audio forward to the precise locaiton
|
|
// if needed.
|
|
// ignore: unused_local_variable
|
|
var seconds = event.secondsDelay;
|
|
|
|
if (event.name == 'Step') {
|
|
_audioPlayer.seek(Duration.zero);
|
|
_audioPlayer.play();
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.removeEventListener(onRiveEvent);
|
|
_controller.dispose();
|
|
_audioPlayer.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Event Sounds'),
|
|
),
|
|
body: Stack(
|
|
children: [
|
|
Center(
|
|
child: RiveAnimation.asset(
|
|
'assets/event_sounds.riv',
|
|
fit: BoxFit.cover,
|
|
onInit: _onRiveInit,
|
|
),
|
|
),
|
|
const Align(
|
|
alignment: Alignment.topCenter,
|
|
child: Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: Text(
|
|
'Sound on!',
|
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|