Repository navigation
fix(markerview): track native marker position in the shadow tree instead of echoing it through JS - #4359
Merged
Conversation
…ead of echoing it through JS Mapbox positions marker views natively (translationX/Y on Android, the annotation view's frame on iOS), which the shadow tree doesn't see, so measure()/measureInWindow() returned the Yoga position and Pressable cancelled presses as soon as the finger moved (#3832). #4176 fixed this on Android by sending every position change to JS and re-rendering a matching transform, which costs a React render per marker per frame while the map moves (#4193). RNMBXMarkerViewContent now has a custom C++ shadow node whose getTransform() adds a per-marker offset read from a native side table (RNMBXMarkerViewContentTranslations). Android writes it through JNI when Mapbox sets translationX/Y, iOS from the annotation frame. Nothing is committed while the map moves, and measure is current without a touch, which also fixes move-taps and measureInWindow on iOS. The spec stays interfaceOnly; react-native.config.js registers the custom component descriptor and points autolinking at android/src/main/jni, and the podspec compiles cpp/ on iOS. Fixes #4193
2 of 8 tasks
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #4193
#4176 made
Pressableinside an AndroidMarkerViewsurvive finger movement by sending every native position change to JS (onAnnotationPosition) and re-rendering a matching transform. That's a React render per marker per frame while the map moves, which is the jank in #4193.This removes the echo.
RNMBXMarkerViewContentgets a custom C++ shadow node whosegetTransform()adds the marker's on-screen offset, read from a small native side table keyed by surface and tag. Android writes it through JNI when Mapbox setstranslationX/Y; iOS writes it when Mapbox sets the annotation view's frame. Nothing is committed while the map moves, andmeasure/measureInWindoware current without a touch. The spec staysinterfaceOnly;react-native.config.jsregisters the custom descriptor and points autolinking atandroid/src/main/jni/CMakeLists.txt, and the podspec compilescpp/.It also fixes iOS: a press with a slightly moving finger on a
MarkerViewwas cancelled on main (0/3, the #3832 bug on iOS), andmeasureInWindowreturned the Yoga position.measureInWindowafter camera move, no touchgetPointInViewVerified on RN 0.79.7 (Android, iOS, iOS static frameworks), the example app on RN 0.84, and Expo 54 and 57 installed from a packed tarball (descriptor registered and JNI symbols present in
libappmodules.so).Known limitations: values computed at commit time (IntersectionObserver, Android
overflowInset) don't update every frame anymore. iOSMarkerViewinside an RNModalisn't covered (same as before). Second-finger taps and tapping a child that overflows the marker on iOS fail on main too and are left for separate fixes.Checklist
CONTRIBUTING.mdyarn generatein the root folder/exampleapp./example)Component to reproduce the issue you're fixing
Jank: render a few hundred markers and pan/zoom (Android, profileable release,
dumpsys gfxinfo). Taps: press the marker while moving the finger ~6dp, after panning or duringsetCameraanimations;measureInWindowshould matchgetPointInView(coordinate).