2d-inc / Flare-Flutter

Load and get full control of your Rive files in a Flutter project using this library.
https://rive.app/
MIT License
2.55k stars 470 forks source link

Animation doesn't start until after the first positive time-step #262

Closed ravenblackx closed 3 years ago

ravenblackx commented 4 years ago

In a test:

await tester.pumpWidget(someWidgetWithAnAnimatingFlareActor);
await tester.pump(Duration(milliseconds: 400));
await expectLater(find.byType(Scaffold).first, matchesGoldenFile('animation_at_400ms'));

doesn't work - the animation will actually be at the 0ms position.

await tester.pumpWidget(someWidgetWithAnAnimatingFlareActor);
await tester.pump();
await tester.pump(Duration(milliseconds: 400));
await expectLater(find.byType(Scaffold).first, matchesGoldenFile('animation_at_400ms'));

Same, doesn't work.

await tester.pumpWidget(someWidgetWithAnAnimatingFlareActor);
await tester.pump(Duration(milliseconds: 1));
await tester.pump(Duration(milliseconds: 400));
await expectLater(find.byType(Scaffold).first, matchesGoldenFile('animation_at_400ms'));

Works, (though at that point the animation should be at 401ms not at 400ms, and it's not!).

I think if, in flare_render_box.dart, you made _lastFrameTime null for "hasn't been set yet" rather than using 0 for unset, then pump(no duration) would update it to zero, and pump(some duration) after that would then advance it by that duration, bringing its behavior in line with that of other animations. ie. replace double _lastFrameTime = 0.0; with double _lastFrameTime; replace _lastFrameTime = 0; with _lastFrameTime = null; replace double elapsedSeconds = _lastFrameTime == 0.0 ? 0.0 : t - _lastFrameTime; with double elapsedSeconds = _lastFrameTime == null ? 0.0 : t - _lastFrameTime;

Also, while you're there, might as well replace final double t = timestamp.inMicroseconds / Duration.microsecondsPerMillisecond / 1000.0; with final double t = timestamp.inMicroseconds / Duration.microsecondsPerSecond;

luigi-rosso commented 3 years ago

Hey @ravenblackx, sorry for the delay in replying. As you figured out, the first pump will always start the cycle so whatever time is pumped will not count towards the accumulated elapsed value until the animation cycle has started (after first pump). Your solution for a pump of 0 seconds is good, but we opted to use -1 as the flag instead of null. We'll be submitting this fix shortly to pub.dev. Let us know if that helps solve this for you.

luigi-rosso commented 3 years ago

Give this a shot with flare_flutter: 2.0.6. Thanks again for the feedback.

ravenblackx commented 3 years ago

That did it, thanks.