mapbox / mapbox/mapbox-maps-android

Enhance Viewport State Transition to Idle for Various Camera Interactions

Open
#2,520 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged feature :green_apple:
Dominant language
Kotlin
Stars
578
Forks
161
PR merge metrics
No merged PRs in 30d

Description

We are using FollowPuckViewportState with bearing(FollowPuckViewportStateBearing.SyncWithLocationPuck). However, this viewport state should switch to Idle when the user interacts with the map, presses the compass, or interacts with application functionality that changes the camera position.

In ViewportPluginImpl, there is the following code:

```
private val cameraAnimationsLifecycleListener = object : CameraAnimationsLifecycleListener {
override fun onAnimatorStarting(
type: CameraAnimatorType,
animator: ValueAnimator,
owner: String?
) {
when (owner) {
VIEWPORT_CAMERA_OWNER -> Unit
MapAnimationOwnerRegistry.GESTURES -> {
if (options.transitionsToIdleUponUserInteraction) {
currentCancelable?.cancel()
currentCancelable = null
updateStatus(
ViewportStatus.Idle,
ViewportStatusChangeReason.USER_INTERACTION
)
}
}
}
}
```

This code allows switching to the Idle state when moving the camera with gestures. However, besides gestures, there are also actions like pressing the compass to rotate the camera or programmatic camera changes using methods like flyTo. We would like these camera changes to also trigger the transition to the Idle state.

Currently, we've implemented the desired behavior as follows:
```

camera.addCameraAnimationsLifecycleListener(object : CameraAnimationsLifecycleListener {
override fun onAnimatorCancelling(type: CameraAnimatorType, animator: ValueAnimator, owner: String?) = Unit

override fun onAnimatorEnding(type: CameraAnimatorType, animator: ValueAnimator, owner: String?) = Unit

override fun onAnimatorInterrupting(
type: CameraAnimatorType,
runningAnimator: ValueAnimator,
runningAnimatorOwner: String?,
newAnimator: ValueAnimator,
newAnimatorOwner: String?
) = Unit
override fun onAnimatorStarting(type: CameraAnimatorType, animator: ValueAnimator, owner: String?) {
if (owner != "VIEWPORT_CAMERA_OWNER")
viewport.idle()
}
})
```

In this implementation, we use the hardcoded constant "VIEWPORT_CAMERA_OWNER". To start, it would be helpful to at least have access to this constant:
`const val VIEWPORT_CAMERA_OWNER = "VIEWPORT_CAMERA_OWNER"`
Currently, it is declared as internal in the Mapbox code.

Ideally, we would like to have an API that allows configuring which actions should cause the state to switch to Idle.

Could you also clarify if the current code:

```
if (owner != "VIEWPORT_CAMERA_OWNER")
viewport.idle()
```

could lead to any errors?

The exact same issue exists on iOS as well, where this constant is also inaccessible, and there is no API for configuring which camera actions should switch the viewport to the Idle state.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ViewportPluginImpl at cameraAnimationsLifecycleListener and review how CameraAnimationsLifecycleListener handles animator owners, especially the internal VIEWPORT_CAMERA_OWNER constant. Compare the requested behavior for gestures, compass actions, and programmatic camera changes with the corresponding iOS issue. Done means the supported transition behavior and any configuration or public constant are clarified for both platforms.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.