mirror of
https://github.com/rive-app/rive-flutter.git
synced 2025-05-17 21:36:06 +08:00
feat: adds play and pause to artboard
An oversight from our side. We've previously recommended setting `isActive` to false on the StateMachine or Animation. But this will not propagate down to nested artboards. Diffs= e64daefff feat: adds play and pause to artboard (#7078) 2828b7b01 propagate volume to nested artboards (#7067) 4a9947630 Stop audio in iOS when backgrounded. (#7055) Co-authored-by: Gordon <pggordonhayes@gmail.com>
This commit is contained in:
@ -1 +1 @@
|
||||
024f95b100f1e76940c4dad707e54bb4f48e86d4
|
||||
e64daefffdcd34df6a6cc9f5b54ebc92e0ae89cb
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
- Support for asset audio volume.
|
||||
- Fixed an issue with audio decoder in web build.
|
||||
- Adds `play()`/`pause()` and `isPlaying` to an `Artboard`. This completely stops the artboard from playing (including nested artboards) and stops/starts the animation ticker. Pausing an artboard can be used to reduce resources used for Rive graphics that aren't visible on screen.
|
||||
|
||||
## 0.13.1
|
||||
|
||||
|
@ -11,20 +11,21 @@ class PlayPauseAnimation extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _PlayPauseAnimationState extends State<PlayPauseAnimation> {
|
||||
/// Controller for playback
|
||||
late RiveAnimationController _controller;
|
||||
Artboard? _artboard;
|
||||
|
||||
/// Toggles between play and pause animation states
|
||||
void _togglePlay() =>
|
||||
setState(() => _controller.isActive = !_controller.isActive);
|
||||
bool get isPlaying => _artboard?.isPlaying ?? true;
|
||||
|
||||
/// Tracks if the animation is playing by whether controller is running
|
||||
bool get isPlaying => _controller.isActive;
|
||||
/// Toggles between play and pause on the artboard
|
||||
void _togglePlay() {
|
||||
if (isPlaying) {
|
||||
_artboard?.pause();
|
||||
} else {
|
||||
_artboard?.play();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = SimpleAnimation('idle');
|
||||
// We call set state to update the Play/Pause Icon. This isn't needed
|
||||
// to update Rive.
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
@ -35,10 +36,11 @@ class _PlayPauseAnimationState extends State<PlayPauseAnimation> {
|
||||
),
|
||||
body: RiveAnimation.asset(
|
||||
'assets/off_road_car.riv',
|
||||
animations: const ["idle"],
|
||||
fit: BoxFit.cover,
|
||||
controllers: [_controller],
|
||||
// Update the play state when the widget's initialized
|
||||
onInit: (_) => setState(() {}),
|
||||
onInit: (artboard) {
|
||||
_artboard = artboard;
|
||||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _togglePlay,
|
||||
|
@ -333,7 +333,7 @@ class RiveRenderObject extends RiveRenderBox implements MouseTrackerAnnotation {
|
||||
|
||||
@override
|
||||
bool advance(double elapsedSeconds) =>
|
||||
_artboard.advance(elapsedSeconds, nested: true);
|
||||
_artboard.isPlaying && _artboard.advance(elapsedSeconds, nested: true);
|
||||
|
||||
@override
|
||||
void beforeDraw(Canvas canvas, Offset offset) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:rive/src/core/core.dart';
|
||||
import 'package:rive/src/generated/artboard_base.dart';
|
||||
import 'package:rive/src/rive_core/animation/animation.dart';
|
||||
@ -534,6 +535,26 @@ class Artboard extends ArtboardBase with ShapePaintContainer {
|
||||
@override
|
||||
void onStrokesChanged() {}
|
||||
|
||||
/// Sets `isPlaying` to true. Animations and state machines will play.
|
||||
///
|
||||
/// See [pause], to pause the artboard from advancing/drawing.
|
||||
@mustBeOverridden
|
||||
void play() {}
|
||||
|
||||
/// Sets `isPlaying` to false. Animations and state machines will not play.
|
||||
/// This can be used to reduce resources when the animation is not visible
|
||||
/// in the app.
|
||||
///
|
||||
/// See [play], to play the artboard and continue advancing/drawing.
|
||||
@mustBeOverridden
|
||||
void pause() {}
|
||||
|
||||
/// Indicates if the runtime artboard is active/playing. When `false` no
|
||||
/// artboard animation or state machine will advance. The underlying animation
|
||||
/// ticker is paused.
|
||||
@mustBeOverridden
|
||||
bool get isPlaying => true;
|
||||
|
||||
@override
|
||||
Vec2D get worldTranslation => Vec2D();
|
||||
|
||||
|
@ -29,6 +29,9 @@ class RuntimeArtboard extends Artboard implements CoreContext {
|
||||
Iterable<Core?> get objects => _objects;
|
||||
final Set<Component> _needDependenciesBuilt = {};
|
||||
|
||||
// Indicates if this artboard is playing or paused
|
||||
bool _isPlaying = true;
|
||||
|
||||
@override
|
||||
T? addObject<T extends Core>(T? object) {
|
||||
object?.context = this;
|
||||
@ -168,4 +171,18 @@ class RuntimeArtboard extends Artboard implements CoreContext {
|
||||
.addPostFrameCallback((_) => controller.isActive = true);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void pause() {
|
||||
_isPlaying = false;
|
||||
}
|
||||
|
||||
@override
|
||||
void play() {
|
||||
_isPlaying = true;
|
||||
markNeedsAdvance();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isPlaying => _isPlaying;
|
||||
}
|
||||
|
@ -39,4 +39,13 @@ void main() {
|
||||
expect(artboard.linearAnimations.toList().length, 2);
|
||||
expect(artboard.stateMachines.toList().length, 1);
|
||||
});
|
||||
|
||||
test('Pausing/Playing an artboard', () {
|
||||
final artboard = riveFile.mainArtboard.instance();
|
||||
expect(artboard.isPlaying, true, reason: "Should be true by default");
|
||||
artboard.pause();
|
||||
expect(artboard.isPlaying, false, reason: "Should be false after pause");
|
||||
artboard.play();
|
||||
expect(artboard.isPlaying, true, reason: "Should be true after play");
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user