> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/ja/maps/llms.txt)

# Animations

Camera animations are the means by which camera settings are changed from old values to new values over a period of time. The Maps SDK for Android provides expressive ways of controlling animations. You can animate the camera to move to a new `center` location and to update the `bearing`, `pitch`, `zoom`, `padding`, and `anchor`. Each of these [camera properties](https://docs.mapbox.com/android/ja/maps/guides/camera-and-animation/camera/) can be animated independently through the Maps SDK camera animation system.

> **Note**
> 
> Only one animation instance per camera setting type can run at a time. For example, if an animator that changes the camera's bearing is running, then starting another bearing operator at the same time will cancel the first one and then start running. This prevents the map from jumping between two or more animators of the same type.

## Animation types

The Maps SDK provides high-level, mid-level, and low-level animation APIs that allow you to transition the camera from old values to new values.

> **Note: Using animations to change camera values**
> 
> If you use `MapboxMap.setCamera` to change camera values instead of using an animator, the camera position will change abruptly to the new values instead of an animated change.

### High-level animation APIs

The Maps SDK has a set of ready-to-use functions for animating map camera transitions. These high-level APIs allow you to implement animations quickly, but have limited options for customization. The built-in animation types are:

-   **[`flyTo`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/fly-to.html)** changes the camera's position from the old values to the new values using a combination of zooming and panning in an animated transition that evokes flight.
-   **[`easeTo`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/ease-to.html)** gradually changes the camera's position with an animated transition from the old values to the new values.
-   **[`rotateBy`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/rotate-by.html)** rotates the map to a different bearing with an animated transition.
-   **[`scaleBy`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/scale-by.html)** animates a change in the size of the images on the map.
-   **[`pitchBy`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/pitch-by.html)** animates a change in the pitch of the map.
-   **[`moveBy`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/move-by.html)** instantaneously re-positions the camera with a quick animated transition from the old values to the new values.

You can call these functions with the [`MapboxMap`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps/-mapbox-map/) object. Different parameters will be used depending on the function type, but all these functions support customizing the animation duration and interpolation.

It's important to note that only one high-level animation can run at a time. If a high-level animation starts while another high-level animation is already running, the running animation will be canceled even if the new high-level animation only changes map camera parameters the running one does not use.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/android/ja/android/ja/assets/medias/maps-examples-globe-fly-to-494451d07f6d3a6b6e308b2c408bf246.mp4).

> **Related content (example): [Fly-to camera animation](https://docs.mapbox.com/android/ja/maps/examples/android-view/fly-to-camera-animation/)**
> 
> Animate the camera changes with the fly-to animation. This causes the camera to ease from a starting point to an end destination.

> **Related content (example): [(Compose) Map viewport animation](https://docs.mapbox.com/android/ja/maps/examples/compose/map-viewport-animation/)**
> 
> Showcase the camera animations based on `MapViewportState` API

### Mid-level animation APIs

There are several mid-level animation APIs that you can use to implement animations with more customization options including running multiple animations simultaneously. These APIs offer more flexibility, but require writing more custom code.

Any number of animators extending [`CameraAnimator`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation.animator/-camera-animator/) can be created and started either sequentially or in parallel. In that case, you do not need to register and unregister those animators.

> **Note: For Jetpack Compose users**
> 
> Mapbox Jetpack Compose extension does not directly support mid-level animation APIs, you can still use mid-level animations within `MapEffect`, but it might break the `MapViewportState`.

### Low-level animation APIs

The Maps SDK also has a set of low-level animation APIs. Each camera property can be animated independently through the Android SDK animator framework.

With the low-level animation APIs, any number of animators extending [`CameraAnimator`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation.animator/-camera-animator/) can be created, but you must also register them in the [`CameraAnimationsPlugin`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/) for the map camera to work properly and unregister them when they are no longer needed. You drive the animation lifecycle (start, end, and cancel) directly with the low-level animation API.

> **Note: For Jetpack Compose users**
> 
> Mapbox Jetpack Compose extension does not directly support low-level animation APIs, you can still use mid-level animations within `MapEffect`, but it might break the `MapViewportState`.

## Start a camera animation

### Start a high-level animation event

Camera animations created using the [high-level animations APIs](#high-level-animation-apis) start automatically when they are called. For example, the camera animation will start after you call `mapboxMap.easeTo(cameraOptions, mapAnimationOptions)`, or `mapViewportState.easeTo(cameraOptions, mapAnimationOptions)` in case of Jetpack Compose.

### Start a mid-level animation event

To start camera animations created using the [mid-level animation APIs](#mid-level-animation-apis), use [`CameraAnimationsPlugin.playAnimatorsTogether`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/play-animators-together.html) (to run the animations at the same time) or [`CameraAnimationsPlugin.playAnimatorsSequentially`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/play-animators-sequentially.html) (to run the animations one by one).

This example runs an animation set that consists of bearing and pitch animators executing simultaneously. It's important to note that the bearing and pitch animator objects cannot be reused later without explicit registration, since the [`playAnimatorsTogether`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/play-animators-together.html) function registers them on animation start and unregisters them on animation end or on cancel.

```kotlin
import com.mapbox.maps.plugin.animation.CameraAnimatorOptions.Companion.cameraAnimatorOptions

mapView.camera.apply {
    val bearing = createBearingAnimator(cameraAnimatorOptions(18.0, 20.0) { startValue(15.0) }) {
          duration = 8500
          interpolator = AnticipateOvershootInterpolator()
    }
    val pitch = createPitchAnimator(cameraAnimatorOptions(30.0) { startValue(15.0) }) {
          duration = 2000
    }
    playAnimatorsTogether(bearing, pitch)
}
```

> **Related content (example): [Start camera animations sequentially](https://github.com/mapbox/mapbox-maps-android/blob/main/app/src/main/java/com/mapbox/maps/testapp/examples/camera/LowLevelCameraAnimatorActivity.kt)**
> 
> Use `playAnimatorsSequentially` to update the camera's zoom, pitch, and bearing in sequence.

### Start a low-level animation event

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/android/ja/android/ja/assets/medias/maps-examples-low-level-camera-animator-f1082d66cb945c70380fe3d0b644e32d.mp4).

> **Related content (example): [Using custom camera animations](https://docs.mapbox.com/android/ja/maps/examples/android-view/using-camera-animations/)**
> 
> Animate the map camera to a new position using camera animators. Individual camera properties such as zoom, bearing, and center coordinate can be animated independently.

With the low-level animation APIs, any number of animators extending `CameraAnimator` can be created, but you must also register them in Mapbox Maps Animation Plugin for the map camera to work properly and unregister them when they are no longer needed. You drive the animation lifecycle (start, end, and cancel) directly with the low-level animation API.

To start camera animations created using the [low-level animation APIs](#low-level-animation-apis), use the [`CameraAnimator.start`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation.animator/-camera-animator/start.html) method. For the animator to start, you need to register it first using [`CameraAnimationsPlugin.registerAnimators`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/register-animators.html).

This example constructs three independent animations (bearing, zoom, and pitch) and creates an animation set so they execute simultaneously. The animation can be customized by using the flexible low-level APIs.

```kotlin
import com.mapbox.maps.plugin.animation.CameraAnimatorOptions.Companion.cameraAnimatorOptions

val plugin = mapView.camera
val bearing = plugin.createBearingAnimator(cameraAnimatorOptions(160.0) { startValue = 0.0 }) {
  duration = 8500
  interpolator = AnticipateOvershootInterpolator()
}
plugin.registerAnimators(bearing)
bearing.apply {
  addListener(
    object : Animator.AnimatorListener {
      override fun onAnimationStart(animation: Animator) {}

      override fun onAnimationEnd(animation: Animator) {
        (animation as? CameraAnimator<*>)?.let {
          plugin.unregisterAnimators(it)
        }
      }

      override fun onAnimationCancel(animation: Animator) {
        (animation as? CameraAnimator<*>)?.let {
          plugin.unregisterAnimators(it)
        }
      }

      override fun onAnimationRepeat(animation: Animator) {}
    }
  )
  start()
}
```

> **Related content (example): [Low-level animation API event](https://github.com/mapbox/mapbox-maps-android/blob/main/app/src/main/java/com/mapbox/maps/testapp/examples/OngoingAnimationActivity.kt)**
> 
> Use the `CameraOperator.start` method to start a new animation that changes the camera's pitch.

## Listen for camera animation events

The Maps SDK provides camera animation event listeners that can tell you if a specific event has happened or if *any* camera animation events have happened. The possible events are:

-   The animation is about to start
-   The animation is about to interrupt an already-running animation of the same type
-   The animation is to end
-   The animation is about to be canceled

### Listen for high-level animation API events

If you are using the [high-level animations APIs](#high-level-animation-apis) and want to listen to the whole high-level animation as one instance, provide [`AnimatorListener`](https://developer.android.com/reference/android/animation/Animator.AnimatorListener) as part of the high level animation APIs, for example [`flyTo`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/fly-to.html) when starting the animation.

**Android View**

```kotlin

mapboxMap.flyTo(
  cameraOptions = cameraOptions,
  animatorListener = object : Animator.AnimatorListener {
    override fun onAnimationStart(animation: Animator) {
      // code to be invoked when animation starts
    }

    override fun onAnimationEnd(animation: Animator) {
      // code to be invoked when animation ends
    }

    override fun onAnimationCancel(animation: Animator) {
      // code to be invoked when animation is canceled
    }

    override fun onAnimationRepeat(animation: Animator) {
      // code to be invoked when animation repeats
    }
  }
)
```

**Jetpack Compose**

```kotlin

val mapViewportState = rememberMapViewportState {
  flyTo(cameraOptions = cameraOptions) { isFinished ->
    // code to be invoked when animation ends, either with completion or cancellation
  }
}
MapboxMap(
  modifier = Modifier.fillMaxSize(),
  mapViewportState = mapViewportState,
)
```

### Listen for lower-level animation API events

If you are using the [mid-level](#mid-level-animation-apis) or [low-level animation APIs](#low-level-animation-apis) and want to listen to a specific event, or all events, you can add the regular Android SDK listener as [`CameraAnimator.addListener(listener: AnimatorListener)`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation.animator/-camera-animator/add-listener.html) to any `CameraAnimator`, which extends Android's `ValueAnimator` with all existing functionality.

```kotlin
lowOrMidLevelAnimator.addListener(
    object : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator) {
          // code to be invoked when animation starts
        }
        override fun onAnimationEnd(animation: Animator) {
          // code to be invoked when animation ends
        }
        override fun onAnimationCancel(animation: Animator) {
          // code to be invoked when animation is canceled
        }
        override fun onAnimationRepeat(animation: Animator) {
          // code to be invoked when animation repeats
        }
    }
)
```

### Listen for all animation events

If you want to listen to all events happening to the camera animation system, use [`CameraAnimationsPlugin` `.addCameraAnimationsLifecycleListener(listener: CameraAnimationsLifecycleListener)`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-animations-lifecycle-listener.html). It will report all the logic when an animator of any type (low-level, mid-level, and high-level animation APIs) is about to start, stop, be canceled, or be interrupted. Register the listener using [`CameraAnimationsPlugin.addCameraAnimationsLifecycleListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-animations-lifecycle-listener.html) and unregister it using [`CameraAnimationsPlugin.removeCameraAnimationsLifecycleListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/remove-camera-animations-lifecycle-listener.html).

### Listen for specific animation value change events

The Maps SDK [`CameraAnimationsPlugin`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/) also provides methods to listen to specific value change events:

-   **Change in center point:** [`CameraAnimationsPlugin.addCameraCenterChangeListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-center-change-listener.html)
-   **Change in bearing:** [`CameraAnimationsPlugin.addCameraBearingChangeListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-bearing-change-listener.html)
-   **Change in pitch:** [`CameraAnimationsPlugin.addCameraPitchChangeListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-pitch-change-listener.html)
-   **Change in zoom:** [`CameraAnimationsPlugin.addCameraZoomChangeListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-zoom-change-listener.html)
-   **Change in padding:** [`CameraAnimationsPlugin.addCameraPaddingChangeListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-padding-change-listener.html)
-   **Change in anchor point:** [`CameraAnimationsPlugin.addCameraAnchorChangeListener`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.animation/-camera-animations-plugin/add-camera-anchor-change-listener.html)

> **Related content (playground): [Location Helper](https://labs.mapbox.com/location-helper)**
> 
> To experiment with camera pitch, bearing, tilt, and zoom and get values to use in your code, try our *Location Helper* tool.