Comment on page
Custom Rive RenderObject
Extend RiveRenderObject to perform more advanced operations.
It is possible to have finer control over your Rive animation at runtime by extending
RiveRenderObject
. This allows you to override low-level methods such as advance
, beforeDraw
, and draw
to have more control and optionally perform additional operations. See below for example usage.Note that this is a low-level API, and under most circumstances, it is preferable to make use of
RiveAnimation
or Rive
widgets instead.The following is a basic example that demonstrates how to paint a Rive animation and advance a state machine using a custom RenderObject.
import 'package:flutter/material.dart';
import 'package:rive/math.dart';
import 'package:rive/rive.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyRiveWidget(),
);
}
}
class MyRiveWidget extends StatefulWidget {
const MyRiveWidget({Key? key}) : super(key: key);
@override
State<MyRiveWidget> createState() => _MyRiveWidgetState();
}
class _MyRiveWidgetState extends State<MyRiveWidget> {
Artboard? _riveArtboard;
Future<void> _load() async {
// You need to manage adding the controller to the artboard yourself,
// unlike with the RiveAnimation widget that can handle a lot of this logic
// for you by simply providing the state machine (or animation) name.
final file = await RiveFile.asset('assets/little_machine.riv');
final artboard = file.mainArtboard;
final controller = StateMachineController.fromArtboard(
artboard,
'State Machine 1',
);
artboard.addController(controller!);
setState(() => _riveArtboard = artboard);
}
@override
void initState() {
super.initState();
_load();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _riveArtboard == null
? const SizedBox()
: CustomRiveRenderObjectWidget(
artboard: _riveArtboard!,
fit: BoxFit.contain,
),
),
);
}
}
class CustomRiveRenderObjectWidget extends LeafRenderObjectWidget {
final Artboard artboard;
final BoxFit fit;
final Alignment alignment;
const CustomRiveRenderObjectWidget({
super.key,
required this.artboard,
this.fit = BoxFit.contain,
this.alignment = Alignment.center,
});
@override
RenderObject createRenderObject(BuildContext context) {
return CustomRiveRenderObject(artboard as RuntimeArtboard)
..artboard = artboard
..fit = fit
..alignment = alignment;
}
@override
void updateRenderObject(
BuildContext context, covariant CustomRiveRenderObject renderObject) {
renderObject
..artboard = artboard
..fit = fit
..alignment = alignment;
}
@override
void didUnmountRenderObject(covariant CustomRiveRenderObject renderObject) {
renderObject.dispose();
}
}
class CustomRiveRenderObject extends RiveRenderObject {
CustomRiveRenderObject(super.artboard) {
_artboardReference = artboard;
}
late final RuntimeArtboard _artboardReference;
@override
bool advance(double elapsedSeconds) {
// The super method will update the animation and advance the artboard.
// You can either advance the artboard yourself, or call the super method.
return _artboardReference.advance(elapsedSeconds, nested: true);
// Example showing how to advance the artboard at twice the speed.
return super.advance(elapsedSeconds * 2);
}
@override
void beforeDraw(Canvas canvas, Offset offset) {
// Called before `draw`. Can be used to perform clipping, for example.
super.beforeDraw(canvas, offset);
}
@override
void draw(Canvas canvas, Mat2D viewTransform) {
// Here you can tap into the draw method and perform custom operations.
super.draw(canvas, viewTransform);
}
}
The artboard can be controlled and configured as it normally would, through a
StateMachineController
(or any other animation controller).- Dynamically update component colors at runtime - Make use of a custom Rive render object to change a shape's fill color, accessing it by name. This is helpful for when a color's opacity is animating, but the color needs to be changed at runtime.
- Track a Rive component in Flutter - Track a Rive component’s position at runtime and overlay a Flutter widget or perform additional painting operations.
For additional information on RenderObjects, see the official Flutter examples:
Last modified 4mo ago