Skip to content

feat: support animated camera transitions - #180

Open
xabaras wants to merge 3 commits into
software-mansion:mainfrom
xabaras:feat/animated-camera-transitions
Open

xabaras wants to merge 3 commits into
software-mansion:mainfrom
xabaras:feat/animated-camera-transitions

Conversation

@xabaras

@xabaras xabaras commented Oct 1, 2026

Copy link
Copy Markdown

Summary

  • Adds optional animateCameraPosition (default false) and cameraAnimationDurationMs (default 300) to Map so programmatic cameraPosition updates can animate instead of jumping.
  • Android: uses CameraPositionState.animate(update, durationMs) when enabled; otherwise keeps move. Observes cameraPosition via snapshotFlow + rememberUpdatedState so ephemeral one-shot targets (and updates after map load) are not dropped, and clearing the prop does not cancel an in-flight animate.
  • iOS Apple Maps: uses setRegion(..., animated = true) for subsequent updates (initial factory setup stays instant). Duration is ignored (MapKit only exposes a boolean).
  • iOS Google Maps: uses animateWithCameraUpdate / animateToCameraPosition with CATransaction duration when enabled.
  • Initial camera paint remains instant on all platforms. Desktop/JVM still does not apply post-load camera updates (documented).

Fixes #168.
Supersedes #179 (closed after local validation; this branch includes the post-validation Android/rememberUpdatedState fix).

Test plan

  • Sample app: change camera via the random-position control with animateCameraPosition = true and confirm smooth pan/zoom on Android and iOS (Apple Maps + Google Maps).
  • Confirm default (animateCameraPosition = false) still jumps instantly (backward compatible).
  • Confirm first map load does not animate from a default region.
  • Bounds-based CameraPosition animates correctly on Android and Google Maps iOS.
  • Ephemeral / one-frame cameraPosition pulses still complete animate on Android (my-location / cluster framing style).

Made with Cursor

Paolo Montalto and others added 3 commits October 1, 2026 12:28
Add optional animateCameraPosition and cameraAnimationDurationMs params
to Map so cameraPosition updates can use native animated transitions
instead of always jumping instantly. Fixes software-mansion#168.

Co-authored-by: Cursor <cursoragent@cursor.com>
Consumers often pulse cameraPosition for a single frame. Keying
LaunchedEffect on that prop cancelled animate() when it became null.
Use snapshotFlow + collectLatest so nulling does not abort the transition.

Co-authored-by: Cursor <cursoragent@cursor.com>
snapshotFlow inside LaunchedEffect(mapLoaded) was capturing a stale
(null) cameraPosition from first composition, so later programmatic
moves never applied. Also bridge Google Maps iOS animate APIs across
Utils vs Maps GMSMapView types so iosArm64 compiles.

Co-authored-by: Cursor <cursoragent@cursor.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support animated camera transitions

1 participant