diff --git a/.rive_head b/.rive_head index f3b2078..d112302 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -aea593c2dfdc4eae136ea9aa7fd16ccb305c4854 +38c0d394bc0b1eaf2c64ab20aa074985ba8bfc43 diff --git a/CHANGELOG.md b/CHANGELOG.md index 81d22e4..a5de3ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.13.17 + +- Expose `speedMultiplier` on the `RiveAnimation` and `Rive` widgets. With this you can adjust the playback speed of an animation or state machine. Thanks [tguerin](https://github.com/tguerin) for the contribution. See [423](https://github.com/rive-app/rive-flutter/pull/423) + ## 0.13.16 - Avoid audio init on empty assets. See PR [431](https://github.com/rive-app/rive-flutter/pull/431). diff --git a/lib/src/rive.dart b/lib/src/rive.dart index 297a866..5b740f1 100644 --- a/lib/src/rive.dart +++ b/lib/src/rive.dart @@ -94,6 +94,11 @@ class Rive extends LeafRenderObjectWidget { /// {@endtemplate} final Rect? clipRect; + /// A multiplier for controlling the speed of the Rive animation playback. + /// + /// Default `1.0`. + final double speedMultiplier; + const Rive({ required this.artboard, super.key, @@ -105,6 +110,7 @@ class Rive extends LeafRenderObjectWidget { this.fit = BoxFit.contain, this.alignment = Alignment.center, this.clipRect, + this.speedMultiplier = 1.0, }); @override @@ -121,7 +127,8 @@ class Rive extends LeafRenderObjectWidget { ..tickerModeEnabled = tickerModeValue ..enableHitTests = enablePointerEvents ..cursor = cursor - ..behavior = behavior; + ..behavior = behavior + ..speedMultiplier = speedMultiplier; } @override @@ -139,12 +146,14 @@ class Rive extends LeafRenderObjectWidget { ..tickerModeEnabled = tickerModeValue ..enableHitTests = enablePointerEvents ..cursor = cursor - ..behavior = behavior; + ..behavior = behavior + ..speedMultiplier = speedMultiplier; } } class RiveRenderObject extends RiveRenderBox implements MouseTrackerAnnotation { RuntimeArtboard _artboard; + double _speedMultiplier = 1; RiveRenderObject( this._artboard, { this.behavior = RiveHitTestBehavior.opaque, @@ -167,6 +176,14 @@ class RiveRenderObject extends RiveRenderBox implements MouseTrackerAnnotation { markNeedsLayout(); } + double get speedMultiplier => _speedMultiplier; + + set speedMultiplier(double value) { + if (value != _speedMultiplier) { + _speedMultiplier = value; + } + } + /// Local offset to global artboard position Vec2D _toArtboard(Offset local) { final globalCoordinates = localToGlobal(local); @@ -333,7 +350,8 @@ class RiveRenderObject extends RiveRenderBox implements MouseTrackerAnnotation { @override bool advance(double elapsedSeconds) => - _artboard.isPlaying && _artboard.advance(elapsedSeconds, nested: true); + _artboard.isPlaying && + _artboard.advance(elapsedSeconds * _speedMultiplier, nested: true); @override void beforeDraw(Canvas canvas, Offset offset) { diff --git a/lib/src/widgets/rive_animation.dart b/lib/src/widgets/rive_animation.dart index d80f2da..bfa47eb 100644 --- a/lib/src/widgets/rive_animation.dart +++ b/lib/src/widgets/rive_animation.dart @@ -71,6 +71,11 @@ class RiveAnimation extends StatefulWidget { /// rendering. final ObjectGenerator? objectGenerator; + /// A multiplier for controlling the speed of the Rive animation playback. + /// + /// Default `1.0`. + final double speedMultiplier; + /// Creates a new [RiveAnimation] from an asset bundle. /// /// *Example:* @@ -92,6 +97,7 @@ class RiveAnimation extends StatefulWidget { this.onInit, this.behavior = RiveHitTestBehavior.opaque, this.objectGenerator, + this.speedMultiplier = 1, Key? key, }) : name = asset, file = null, @@ -121,6 +127,7 @@ class RiveAnimation extends StatefulWidget { this.headers, this.behavior = RiveHitTestBehavior.opaque, this.objectGenerator, + this.speedMultiplier = 1, Key? key, }) : name = url, file = null, @@ -148,6 +155,7 @@ class RiveAnimation extends StatefulWidget { this.onInit, this.behavior = RiveHitTestBehavior.opaque, this.objectGenerator, + this.speedMultiplier = 1, Key? key, }) : name = path, file = null, @@ -176,6 +184,7 @@ class RiveAnimation extends StatefulWidget { this.clipRect, this.controllers = const [], this.onInit, + this.speedMultiplier = 1, Key? key, this.behavior = RiveHitTestBehavior.opaque, }) : name = null, @@ -346,6 +355,7 @@ class RiveAnimationState extends State { clipRect: widget.clipRect, enablePointerEvents: _shouldAddHitTesting, behavior: widget.behavior, + speedMultiplier: widget.speedMultiplier, ) : widget.placeHolder ?? const SizedBox(); } diff --git a/pubspec.yaml b/pubspec.yaml index a76eee3..ff6f8d2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: rive -version: 0.13.16 +version: 0.13.17 homepage: https://rive.app description: Rive Flutter Runtime. This package provides runtime functionality for playing back and interacting with animations built with the Rive editor available at https://rive.app. repository: https://github.com/rive-app/rive-flutter