Question: How can I replace a component?
I have a .riv file which contains a static svg image (without any animations).
File structure: artboard->image.svg/group1/group2/(groupA/groupB/groupC). Groups A, B, C contain various shapes, ellipses, etc.
I have two questions:
-
Can I change the visibility of groupC so that the image does not show objects from this group?
-
Can I remove groupC and add groupD to the file instead? I have tried removing the group in many different ways, but the image stays the same.
RiveFile riveFile = await RiveFile.asset('assets/images/rive.riv');
var set = riveFile.mainArtboard
.children.elementAt(0) // image.svg
.dependents.elementAt(0) // group1
.dependents.elementAt(0) //group2
.dependents; //groupA/groupB/groupC
var groupC = set.firstWhere((element) => element.name == 'groupC');
groupC.remove();
groupC.onRemoved();
...
return Scaffold(
body: Center(
child: Rive(
artboard: riveFile!.mainArtboard,
fit: BoxFit.fitWidth,
alignment: Alignment.center,
),
),
);
I would appreciate your help, thanks.
Hi! At the moment we don't expose an API to achieve the component swapping like you mentioned. You can delve down a deeper level and potentially achieve the results you are looking for at a painting level. Take a look at this sample repo demoing how to change the opacity/color of components: https://github.com/HayesGordon/rive_flutter_runtime_color_change_example
We will be releasing a new feature soon, called Solos, this will allow you to turn certain components on/off (for example you define A, B, and C and then you can choose to display one of those and turn the others off) - which means you'll be able to easily configure this within the editor and it'll be an efficient way to do it. You can technically already do this by setting up multiple animations (that hide show relevant sections) and controlling it with a state machine.
Solos has release, more information for anyone interested: https://www.youtube.com/watch?v=4z364R6YpJw
Solos has release, more information for anyone interested: https://www.youtube.com/watch?v=4z364R6YpJw
Thank you! Could you provide a link to a usage example on flutter?
Here is some example code. It'll require you to import src code that is not exported in the library. In the future there may be a better API to do this.
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
// NOTE THESE IMPORTS
import 'package:rive/src/rive_core/solo.dart';
import 'package:rive/src/container_children.dart';
class SoloSwitchExample extends StatefulWidget {
const SoloSwitchExample({Key? key}) : super(key: key);
@override
State<SoloSwitchExample> createState() => _SoloSwitchExampleState();
}
class _SoloSwitchExampleState extends State<SoloSwitchExample> {
late Solo mySolo;
late ContainerChildren soloChildren;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
// Switch between the two children in the SOLO. You can
// make this more robust. This is just an example
if (mySolo.activeComponent == soloChildren[0]) {
mySolo.activeComponent = soloChildren[1];
} else {
mySolo.activeComponent = soloChildren[0];
}
},
child: const Text('go')),
Expanded(
child: RiveAnimation.asset(
'assets/solo_sample.riv',
fit: BoxFit.cover,
onInit: (artboard) {
// This is where you can get the Solo object
for (var element in (artboard as RuntimeArtboard).objects) {
if (element is Solo) {
print(element.name);
for (var element in element.children) {
print(element.name);
}
mySolo = element;
soloChildren = mySolo.children;
}
}
},
),
),
],
),
),
);
}
}
If you have multiple solos you should also do a check to make sure the name matches. For example:
if (element.name == "MySolo") // do something

https://github.com/rive-app/rive-flutter/assets/13705472/83a60d5b-d5e7-4396-b47e-222d8cf532a0
I'm closing this issue for now as Component swapping is not something we're looking into supporting directly through our high-level runtimes.