diff --git a/lib/src/rive.dart b/lib/src/rive.dart index 297a8667..5b740f14 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 d80f2dac..bfa47eb7 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(); }