rive-flutter
rive-flutter copied to clipboard
Nested artboard not shown on embedding one
<-- Thanks for using Rive!
If something isn't working like you expected, please:
- Make sure you've updated rive-flutter to the latest version: https://pub.dev/packages/rive/versions
- Check out our help center https://help.rive.app/
- You can file a new feature request at https://feedback.rive.app/
If you think you found a bug or if you can't find what you're looking for in our docs, fill out the template below.
-->
Description
After designing several tiny animations on different artboards we tried to build bigger animations by nesting the tiny ones into a sequence on a new artboard.
Steps To Reproduce
Steps to reproduce the behavior: See example, here the Rive widget is shown on the first screen. untitled2.zip
Source .riv
/.rev
file
See example assets.
Expected behavior
Show the nested artboard correctly.
Screenshots
In rive.app
In flutter app
Device & Versions (please complete the following information)
Flutter 2.5.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 18116933e7 (8 weeks ago) • 2021-10-15 10:46:35 -0700
Engine • revision d3ea636dc5
Tools • Dart 2.14.4
+1 Having similar issue.
any news about this in the meantime?
Also checked on 0.8.4. Issue is still occuring.
+1 Having the same issue. Although the nested artboard animations are working fine, the real problem is using them in a State Machine. The issue might be related with StateMachineController
The bug is with
rootBundle.load('assets/...riv').then(
(data) async {
// Load the RiveFile from the binary data.
final file = RiveFile.import(data);
}
Then nested artboard works if you use RiveAnimation.asset() but not with RiveFile.import(data)
Any workarounds here? I cannot use RiveAnimation.asset() because I need to use a state machine controller and I guess that's not possible using RiveAnimation, or is it?
If you could get the artboard from
RiveAnimation.asset()
you could put into
StateMachineController.fromArtboard(artboard, 'state machine name');
, but at the moment you only can get the artboard's name like an String...
@mikeesouth You can set up an onInit
callback on RiveAnimation.asset
and get a reference to a StateMachineController
from there like @nmarafo mentions above.
void _onInit(Artboard artboard) {
final smController = StateMachineController.fromArtboard(artboard, 'state machine name');
...
}
...
RiveAnimation.asset(
'foo.riv',
onInit: _onInit
)
We'll look into the RiveFile
issue though, as that seems to be reproducible
@zplata & @nmarafo thanks for your suggestions. This solution works, thanks! The downside for me is that RiveAnimation is initializing the artboard in initState() which is called when adding the RiveAnimation to the widget tree in Flutter. This is OK but the RiveFile.import() method let's me initialize the artboard without drawing the Rive artboard to the screen, thus giving me more flexibility.
I reuse my Rive asset between different screens by caching the artboard in local state. This allows me to keep state controller states and animations between page navigations. I simply add Rive(artboard: _myCachedArtboard)
to the widget tree and it's already initialized and animations are kept.
I did achieve this with the RiveAnimation constructors too. The way I did this was to call RiveAnimation.asset() in the first screen in my app and let that RiveAnimation be drawed on the screen. As soon as it's drawn, onInit() is called and I cache the artboard. When it's cached, I change the Rive representation to Rive(artboard: _myCachedArtboard)
(instead of RiveAnimation). The only downside with this is that I have to add the RiveAnimation to the build() method so that initState() is called once. With RiveFile.import() I could do this in my application startup code without adding the RiveAnimation to the build() tree.
I'm looking forward to a fix with RiveFile too, that would be awesome @zplata 👍
Hi @mikeesouth, thanks for your answer. How could you cached the artboard from RiveAnimation? you take it from smController? For example:
StateMachineController? smController;
void _onInit(Artboard artboard) {
smController = StateMachineController.fromArtboard(artboard, 'state machine name');
}
RiveAnimation.asset(
'rive_file.riv',
onInit: _onInit,
)
Artboard? artboard=smController.artboard;
@nmarafo I'm taking it from the _onInit parameter:
void _onInit(Artboard artboard) {
_myCachedArtboard = artboard;
}
And I build it using Rive(artboard: _myCachedArtboard)
instead of RiveAnimation()
to prevent initState() of RiveAnimation to trigger an init every time I add the Rive asset to new screens.
@MarcMolitorAtDermalog and all interested: In this case, to get the nested artboard to show through, you should instance the Artboard
when you set it up with the Rive
widget, so your setup would go from:
Rive(artboard: riveFile.artboardByName("artboard"));
to
Rive(artboard: riveFile.artboardByName("artboard")!.instance());
This clones the internals, including the nested artboard appropriately. We may change this in the future to make this simplified so that you don't need to call .instance()
if you set up the Artboard manually.
If you're interested, here, you can see RiveAnimation
doing the same thing.
@MarcMolitorAtDermalog and all interested: In this case, to get the nested artboard to show through, you should instance the
Artboard
when you set it up with theRive
widget, so your setup would go from:Rive(artboard: riveFile.artboardByName("artboard"));
to
Rive(artboard: riveFile.artboardByName("artboard")!.instance());
This clones the internals, including the nested artboard appropriately. We may change this in the future to make this simplified so that you don't need to call
.instance()
if you set up the Artboard manually.If you're interested, here, you can see
RiveAnimation
doing the same thing.
this solution worked for me! Thank you @zplata 💯
@karebae that solution is not working for me as i have two nested artboard and in animation 2nd one is overlayed on first one and if i directly assign the artboard
rootBundle.load(Assets.modelsSwiftFly).then( (data) { final file = RiveFile.import(data); riveFile = file; final artboard = riveFile?.mainArtboard; StateMachineController.fromArtboard( artboard!, 'State Machine 1', onStateChange: (stateMachineName, animationName) { debugPrint(stateMachineName); debugPrint(animationName); debugPrint("${trigger?.value}"); // _selectedInput = // switchMode(); }, );
like this the second artboared which is animating insect is not apearing 😩
and when i fetch the animation using RiveAnimation.asset
this it's work but this way i can't give any input if anyone knows how to give input in RiveAnimation.asset
feel free to share 🤗