You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm building a Flutter app using maplibre_gl (Flutter plugin). During a "POI sweep" feature, the camera needs to fly continuously along a GPS track polyline while I query queryRenderedFeaturesInRect at each step (the orginal polyline is simplified to steps at every 50 gps points or 20 gpx points, I tried different approaches). No matter what approach I try, the camera either pauses or stutters at each step instead of moving continuously.
Result: Still stops at each step. Each new animateCamera call interrupts the previous one and starts from the current position — but since the delay is shorter than the animation, there is a visible jerk/pause as the direction changes abruptly at each waypoint.
AnimationController (60 Hz) + moveCamera
We decoupled the camera from the query loop entirely. A Flutter AnimationController ticks at 60 fps and calls moveCamera (instant, no internal animation) every tick, with position computed via a Catmull-Rom spline parameterised by arc-length:
final flyCtrl = AnimationController(vsync: this, duration: duration);
flyCtrl.addListener(() {
// compute lat/lng via Catmull-Rom at current animation value
_mlController!.moveCamera(
CameraUpdate.newCameraPosition(CameraPosition(target: LatLng(lat, lng), zoom: 11)),
);
});
await flyCtrl.forward();
flyCtrl.dispose();
The camera task and query task run concurrently via Future.wait([_flyAlongTrack(...), _querySweep(...)]).
Result: Still appears to stutter. Our theory is that moveCamera platform channel calls are queued on the platform side and replayed in batches rather than one per frame, causing visible stutters.
Pre-sample ~150 positions along the Catmull-Rom curve, then fire overlapping animateCamera calls where each animation duration is 60% longer than the interval between fires, so the camera should always be mid-animation when the next target arrives:
final numFrames = (totalDuration.inMilliseconds / 600).round().clamp(20, 150);
final intervalMs = totalDuration.inMilliseconds / (numFrames - 1);
final animDuration = Duration(milliseconds: (intervalMs * 1.6).round());
for (final pos in positions) {
_mlController!.animateCamera(
CameraUpdate.newCameraPosition(CameraPosition(target: pos, zoom: 11)),
duration: animDuration,
).ignore(); // deliberately NOT awaited
await Future.delayed(Duration(milliseconds: intervalMs.round()));
}
Result: Still has visible pauses at each waypoint transition. Even though the overlap factor is > 1, the camera appears to stop briefly at each target before the next animation takes over.
Is there a way in maplibre_gl Flutter to animate the camera along a multi-point path in a single call, rather than chaining point-to-point animations?
Does moveCamera in the Flutter plugin have any internal debouncing or batching that would explain why 60 Hz calls don't produce smooth motion?
Is animateCamera designed to be interrupted mid-flight by a new call and continue from current position, or does it snap/reset when interrupted?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello everyone,
I'm building a Flutter app using maplibre_gl (Flutter plugin). During a "POI sweep" feature, the camera needs to fly continuously along a GPS track polyline while I query queryRenderedFeaturesInRect at each step (the orginal polyline is simplified to steps at every 50 gps points or 20 gpx points, I tried different approaches). No matter what approach I try, the camera either pauses or stutters at each step instead of moving continuously.
Here is a short preview: https://youtube.com/shorts/3Va5HsYfe7M?is=tWCHy6B4ZI8frFXp
What I have tried:
1 . Sequential animateCamera with await
Result: Hard stop at every point. Camera waits for animation to complete, then jumps to next.
Result: Still stops at each step. Each new animateCamera call interrupts the previous one and starts from the current position — but since the delay is shorter than the animation, there is a visible jerk/pause as the direction changes abruptly at each waypoint.
We decoupled the camera from the query loop entirely. A Flutter AnimationController ticks at 60 fps and calls moveCamera (instant, no internal animation) every tick, with position computed via a Catmull-Rom spline parameterised by arc-length:
The camera task and query task run concurrently via Future.wait([_flyAlongTrack(...), _querySweep(...)]).
Result: Still appears to stutter. Our theory is that moveCamera platform channel calls are queued on the platform side and replayed in batches rather than one per frame, causing visible stutters.
Attempt 4 — Pre-sampled Catmull-Rom + overlapping animateCamera (current)
Pre-sample ~150 positions along the Catmull-Rom curve, then fire overlapping animateCamera calls where each animation duration is 60% longer than the interval between fires, so the camera should always be mid-animation when the next target arrives:
Result: Still has visible pauses at each waypoint transition. Even though the overlap factor is > 1, the camera appears to stop briefly at each target before the next animation takes over.
Is there a way in maplibre_gl Flutter to animate the camera along a multi-point path in a single call, rather than chaining point-to-point animations?
Does moveCamera in the Flutter plugin have any internal debouncing or batching that would explain why 60 Hz calls don't produce smooth motion?
Is animateCamera designed to be interrupted mid-flight by a new call and continue from current position, or does it snap/reset when interrupted?
Any other suggestion what I might try ?
Beta Was this translation helpful? Give feedback.
All reactions