I am a beginner to rive
and flutter
. I am building a favorite items page in flutter
. If there are not anything added to favorites I need to show a riveAnimation
on screen. I already implemented almost everything to show the animation
on screen. But I need to toggle a jumping animation when user tap on the animation which is really cool. for now I have the animation on 'Idle' mode
You may want to refer to the rive
file =>
The code and the image may be little bit bigger. Sorry about that
class Favourites extends StatefulWidget {
Favourites({Key? key}) : super(key: key);
@override
State<Favourites> createState() => _FavouritesState();
}
class _FavouritesState extends State<Favourites> {
String animation = 'idle';
SMIInput<String>? _birdInput;
Artboard? _birdArtboard;
void jump() {
setState(() {
_birdInput?.value = 'Pressed';
});
}
@override
void initState() {
super.initState();
rootBundle.load('assets/rive/bird.riv').then(
(data) {
final file = RiveFile.import(data);
final artboard = file.mainArtboard;
var controller = StateMachineController.fromArtboard(
artboard,
'Bird',
);
if (controller != null) {
artboard.addController(controller);
_birdInput = controller.findInput('Pressed');
}
setState(() => _birdArtboard = artboard);
},
);
}
@override
Widget build(BuildContext context) {
final favourite = Provider.of<Favourite>(context);
return Scaffold(
backgroundColor: Colors.grey[300],
appBar: const CustomAppBar(title: 'Favourites'),
body: favourite.items.isEmpty
? Center(
child: Column(
children: [
SizedBox(
width: 300,
height: 500,
child: _birdArtboard == null
? const SizedBox()
: Center(
child: GestureDetector(
onTap: () {},
child: Rive(artboard: _birdArtboard!),
),
),
),
NeumorphicButton(),
],
),
)
: CustomGrid(),
);
}
}
CodePudding user response:
If you open/run rive file on rive site, you can find that it is using Trigger
variable for jumping and it is using State Machine 1
state machine.
Next thing comes about declaring variable. You need to use SMITrigger
data type for this and use StateMachineController
to control the animation.
Use .findSMI(..)
instead of .findInput()
for SMITrigger
.
To start animation on trigger, use
trigger?.fire();
I will encourage you to take a look on editor and check input variable type while performing rive animation.
So the full widget that will provide animation is
class Favourites extends StatefulWidget {
const Favourites({Key? key}) : super(key: key);
@override
State<Favourites> createState() => _FavouritesState();
}
class _FavouritesState extends State<Favourites> {
String animation = 'idle';
Artboard? _birdArtboard;
SMITrigger? trigger;
StateMachineController? stateMachineController;
@override
void initState() {
super.initState();
rootBundle.load('assets/rive/bird.riv').then(
(data) {
final file = RiveFile.import(data);
final artboard = file.mainArtboard;
stateMachineController =
StateMachineController.fromArtboard(artboard, "State Machine 1");
if (stateMachineController != null) {
artboard.addController(stateMachineController!);
trigger = stateMachineController!.findSMI('Pressed');
stateMachineController!.inputs.forEach((e) {
debugPrint(e.runtimeType.toString());
debugPrint("name${e.name}End");
});
trigger = stateMachineController!.inputs.first as SMITrigger;
}
setState(() => _birdArtboard = artboard);
},
);
}
void jump() {
trigger?.fire();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: Center(
child: Column(
children: [
SizedBox(
width: 300,
height: 400,
child: _birdArtboard == null
? const SizedBox()
: Center(
child: GestureDetector(
onTap: () {
jump();
},
child: Rive(artboard: _birdArtboard!),
),
),
),
],
),
));
}
}