Can't get rotation to take effect
davystrong opened this issue · 4 comments
I can't get the rotation I set to take effect. I tried to set the rotation inside my controller (extending FlareControls) but it doesn't update unless I play an animation. As the change is very small, I don't want to animate. Any suggestions?
It sounds like your code might not be activating the controller properly.
Could you post it, together with your Rive file?
The code:
class HourHand extends StatefulWidget {
const HourHand({Key key, this.time, this.color}) : super(key: key);
final DateTime time;
final Color color;
@override
_HourHandState createState() => _HourHandState();
}
class _HourHandState extends State<HourHand> {
_HourController hourController = _HourController();
@override
Widget build(BuildContext context) {
hourController.time = widget.time;
return FlareActor(
'assets/animations/HourHand.flr',
color: widget.color,
controller: hourController,
);
}
}
class _HourController extends FlareControls {
FlutterActorArtboard artboard;
@override
void initialize(FlutterActorArtboard artboard) {
super.initialize(artboard);
this.artboard = artboard;
}
set time(DateTime time) {
if (artboard != null) {
ActorBone baseAngleBone = artboard.getNode('BaseAngle') as ActorBone;
baseAngleBone.rotation =
(time.hour * 30 + time.minute * 0.5 + time.second / 120 - 90) /
180 *
pi;
//This is weird. The rotation doesn't update unless I play an animation
play('Idle');
}
}
}
Link to the rive file:
https://rive.app/a/davystrong/files/flare/hour-hand-2
If you take a look at the play()
function in FlareControls
, it adds the animation to the list of animations controlled by FlareControls
and activates the Controller itself.
The flag contained in the ValueNotifier isActive
is necessary for FlareActor
to know that the controller is indeed active, and marks FlareActor
for painting.
So instead of playing the idle animation, you can just do:
set time(DateTime time) {
if (artboard != null) {
ActorBone baseAngleBone = artboard.getNode('BaseAngle') as ActorBone;
baseAngleBone.rotation =
(time.hour * 30 + time.minute * 0.5 + time.second / 120 - 90) /
180 *
pi;
isActive.value = true;
}
}
@override
bool advance(FlutterActorArtboard artboard, double elapsed) {
// De-activate the controller, and stop advancing.
isActive.value = false;
return false;
}
Great, that seems to have worked! I hadn't realized I could change the value of isActive
. Thanks for your help!