Skip to content

[Bug]: MarkerView drift on Android during pan/zoom with @rnmapbox/maps@10.3.2 #4276

Closed as not planned

Description

@jleprinc

Mapbox Version

11.23.1

React Native Version

0.85.3

Platform

Android

@rnmapbox/maps version

10.3.2

Standalone component to reproduce

import Mapbox, { Camera, CircleLayer, MapView, MarkerView, ShapeSource } from "@rnmapbox/maps"
import React from "react"
import { StyleSheet, Text, View } from "react-native"

// Set your own public Mapbox access token (never commit a real one).
Mapbox.setAccessToken(process.env.EXPO_PUBLIC_MAPBOX_ACCESS_TOKEN ?? "REPLACE_WITH_YOUR_OWN_MAPBOX_ACCESS_TOKEN")

// Paris, arbitrary — any two nearby points work.
const CENTER = [2.3522, 48.8566]
const POIS = [
  { id: "a", coordinate: [2.3522, 48.8566], label: "120 m" },
  { id: "b", coordinate: [2.3572, 48.8596], label: "340 m" },
]

// Plain dot on a ShapeSource/CircleLayer — a native GL layer, no image asset,
// no RN bridge per-frame, so it never drifts: this is the reference.
const DOT_RADIUS = 18

const dotShape = {
  type: "FeatureCollection",
  features: POIS.map((poi) => ({
    type: "Feature",
    id: poi.id,
    geometry: { type: "Point", coordinates: poi.coordinate },
    properties: {},
  })),
}

const dotLayerStyle = {
  circleRadius: DOT_RADIUS,
  circleColor: "#2a9d8f",
  circleStrokeWidth: 2,
  circleStrokeColor: "white",
}

// Same pattern as a typical distance-label marker: a MarkerView pinned at the
// same coordinate as the dot, offset above it. This is a real RN view
// re-projected by rnmapbox every frame — this is the one that drifts on
// Android pan/zoom while the CircleLayer dot above stays glued to its
// coordinate.
const LABEL_GAP = 10

export default function App() {
  return (
    <View style={styles.container}>
      <MapView style={styles.map} styleURL={Mapbox.StyleURL.Street}>
        <Camera zoomLevel={13} centerCoordinate={CENTER} />

        <ShapeSource id="dots-shape-source" shape={dotShape}>
          <CircleLayer id="dots-circle-layer" style={dotLayerStyle} />
        </ShapeSource>

        {/* Drag the map on Android: the label drifts away from its dot. */}
        {POIS.map((poi) => (
          <MarkerView
            key={poi.id}
            coordinate={poi.coordinate}
            anchor={{ x: 0.5, y: 1 }}
            pointerEvents="none"
          >
            <View style={styles.labelOffset} pointerEvents="none">
              <View style={styles.labelBadge}>
                <Text style={styles.labelText}>{poi.label}</Text>
              </View>
            </View>
          </MarkerView>
        ))}
      </MapView>
    </View>
  )
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  map: { flex: 1 },
  // anchor {x:0.5, y:1} pins the label's bottom-center to the coordinate, then
  // this pushes it straight up, clear of the dot's radius + a gap.
  labelOffset: { transform: [{ translateY: -(DOT_RADIUS + LABEL_GAP) }] },
  labelBadge: {
    backgroundColor: "#ffb703",
    borderColor: "black",
    borderWidth: 1,
    borderRadius: 8,
    paddingHorizontal: 6,
    paddingVertical: 2,
  },
  labelText: { fontSize: 12, fontWeight: "700", color: "black" },
})

Observed behavior and steps to reproduce

Marker is drifting compare to symbol layer even with only 2 markers and a really simple app when user pan/zoom on the map

  • Add the App.js in your react native/expo project
  • Pan the map

Expected behavior

MarkerView shouldn't be drifting

Notes / preliminary analysis

Happens since May 24, @rnmapbox/maps 10.2.10 → 10.3.1.

What changed: not RN/Expo (those bumped in separate commits, 0.79→0.85 across 7af7239be/348d82d74/9e32a2097). The rnmapbox bump itself is what did it — 10.3.0 hard-forces native Mapbox v10 → v11 (gradle: "❌ ERROR: Mapbox v10 is no longer supported as of @rnmapbox/maps 10.3.0"). Mapbox v10 (what you ran on RN 0.79) didn't have the MarkerView drift; v11 does.

I know in this small example I can use symbolLayer for all the elements, but in my app I need to use animations (zoomIn/zoom out, transform,...) and not just static images so I need to use MarkerView

Additional links and references

screen-20260806-100640-1786003595885.mp4

Activity

  1. mfazekas commented on Oct 13, 2026

    @mfazekas
    Contributor

    Thanks for the clear reproducer! We reproduced it on current main and looked into where the lag comes from.

    MarkerView on Android is positioned by Mapbox's own ViewAnnotationManager, and it already uses the synchronized update mode by default. A plain native Android view added directly as a Mapbox view annotation (no React Native involved) trails the map by the same amount as MarkerView, so this is a limitation of view annotations in the Mapbox Android SDK rather than something in our wrapper. The map is drawn on its own surface and composited separately from the normal view hierarchy, so during a pan the view can end up a frame behind. Mapbox describes the same limitation in mapbox/mapbox-maps-android#1609.

    The likely reason you first noticed it after upgrading: in 10.3.0 (#4166) the Android surfaceView default became true for everyone.

    Options:

    1. If the marker must stay exactly on the coordinate, render it as a SymbolLayer (with Images); layers are drawn as part of the map, so they never drift.
    2. Try <MapView surfaceView={false}> (TextureView). In our measurements the marker then no longer trails the map, but it leads it by a similar amount, and TextureView has some performance cost.
    3. Keep MarkerView where you need animated or interactive content, and accept the small lag while the map moves.

    Since there's nothing we can fix on our side, I'm closing this as an upstream limitation. Feel free to reopen if you find a case where MarkerView lags more than a plain Mapbox view annotation.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🪲Something isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions