Closed do4Mother closed 3 years ago
Hi there!
While the SimpleAnimation controller is really intended for playing an animation either once or in a loop, you can use it to play different animations on-demand by adding and removing controllers from the artboard. Adding a SimpleAnimation will start that animation immediately, and if you want to replay it, simply remove and re-add the animation.
If you want more flexibility, the recommendation would be to create a custom controller to handle how you want different animations to play and mix together.
Here's a simple example that triggers two animations on button press:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rive/rive.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SimpleAnimation _animation1, _animation2;
void _playAnimation1() {
// Remove the controller if necessary
_riveArtboard.removeController(_animation1);
// Add the controller to fire the animation
_riveArtboard.addController(_animation1);
}
void _playAnimation2() {
_riveArtboard.removeController(_animation2);
_riveArtboard.addController(_animation2);
}
Artboard _riveArtboard;
@override
void initState() {
super.initState();
rootBundle.load('assets/loader.riv').then(
(data) async {
final file = RiveFile();
if (file.import(data)) {
final artboard = file.mainArtboard;
// Create controllers for the one-shot animations you want to
// repeatedly fire
_animation1 = SimpleAnimation('load');
_animation2 = SimpleAnimation('end');
// Initially show the animation in its idle state
artboard.addController(SimpleAnimation('idle'));
setState(() => _riveArtboard = artboard);
}
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: [
Expanded(
child: _riveArtboard == null
? const SizedBox()
: Rive(artboard: _riveArtboard),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: FlatButton(
child: Text('Play Animation 1'),
onPressed: _playAnimation1,
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: FlatButton(
child: Text('Play Animation 2'),
onPressed: _playAnimation2,
),
),
]),
);
}
}
Thank you so much for your help. after I tried it, I encountered a problem where the message icon did not work according to the animation design I had made. where the expected result will produce the following
where the animation results that I made like this
Can you post some code that demonstrates the problem? Happy to take a look and help with it.
Can you post some code that demonstrates the problem? Happy to take a look and help with it.
yes, you can try this https://github.com/do4Mother/demo_navigation
thanks
I had a look at the code and it appears fine. The problem is the way the animations are accumulating. When the inactive animation is run, the yellow spots are shrunk and disappear, via the group, shapes and paths. These changes are accumulated and not reset by the active animation, so they end up stuck in that state. By setting keyframes on the values changed by inactive in the active animation, the yellow spots can be shown again.
I've edited your animation file to make the changes; the one attached should now work for you. Let me know if this works!
Here's a link to more info on how values accumulate in Rive: https://github.com/2d-inc/Flare-Flutter/issues/31#issuecomment-453640836 (this is for the older version of Rive, but holds true for this version).
Thank you so much, the chat icon works well!
is there an updated version of this in 2022? the code line final file = RiveFile(); produces below error :- The class 'RiveFile' doesn't have an unnamed constructor. Try using one of the named constructors defined in 'RiveFile'.
and the line if (file.import(data)) { produces below error :- The method 'import' isn't defined for the type 'RiveFile'. Try correcting the name to the name of an existing method, or defining a method named 'import'.
I have 2 animations with the name "active" and "inactive", each of which is a one shot animation. How do I switch between animations?
Thanks