Slide Map Overlay Guide #3606
FrederickEngelhardt
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Mapbox Slide Map Layering Guide
Hi all, I posted a guide for this on my examples repo. But makes sense to post this here too.
----- source document -----
This is a guide on how to do multi-map layering on rnmapbox. Includes working examples of layering two maps.
This is a generic overlay template component for @rnmapbox/map.
Why?
Preface
The following example is inspired by designs and approaches taken while creating the App A Deeper Map.
Building a slide map has some complexities especially with react-native. So this guide aims to show a clear path forward for doing overlays with Maps and other GL layers.
This guide could be used for any react-native component layering.
Consider the following
The solution below is only meant for 2 maps but likely could scale up to 4 maps.
Past 2 maps there could be severe performance issues with both network and device GPU resources since these maps are still rendered but not fully in view.
If you need to do this...you'll want to work with mapbox team and see if there is a way to inject a layer and clip it within the map component.
Steps
1. Clip A View
ReactNative similar to the web has an
overflow
property.In the example above. There are two views. The
BackgroundBlueView
and theClippedOrangeView
.ClippedOrangeView
will expand. But the left side is constrained to 250 meaning the center of the view. Even though the ClippedView is still 500px it will only show 250px of this view.To div deeper into what is going on. It's worth adding different colors to see what is being lost.
The above example would render a purple border make it easy to see if the orange box is in alignment or if it the overflow is pushing off screen elsewhere.
View collapsable=false
On the same object that utilizes
overflow: hidden
add the propcollapsable={false}
which will prevent the View from deflating in size. In some cases, this will help prevent the map from decreasing size when it is clipped.Absolute Position Layering
Next step is to absolutely position two
<MapView />
components. To make this simpler, consider adding two maps with different data but the same location to properly confirm alignment is working.const {width, height }= useWindowDimensions()
or if it's a smaller container use a position relative to allow absolute styling only within that container.The
width
andheight
are required for the container that must be constrained in order to retain the view's size. Without a set width or height, flex and absolute positioning will resizing the window to match the left, top, right, bottom bounds instead of overflowing.Share map syncing logic
When the focused map camera updates, all the unfocused maps would have to update to sync to that position.
Add something like useMapSync to synchronize everything without calling
setState
after a frequent interaction which is not performant.Animating Map Layers
Add sharedValues for the maps
Add Gestures and Update the SharedValues
Final step is to add gestures and fire updates to SharedValues
Wrap a button, corner, or part of the screen you want to intercept interactions with a
GestureDetector
and a PanGesture handler.A button is recommend for semantically showing the user that they can resize a window.
After creating this button we can now determine how we want to compute the pan events.
state.x
orstate.y
.Solution Limitations
Future Potential
react-native-svg
to act as view masks which would embed the map within their clipped hierarchies.Alternatives
Tech
Full Example
This repo contains the full example. Please follow the @vllc/mapbox README.md and the monorepo README.md for installation
Beta Was this translation helpful? Give feedback.
All reactions