From 124fd418d64102a4a2c9040702e4f1a881c0af6c Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 06:27:54 +0800 Subject: [PATCH 1/9] feat: add setEdgeInsets native command with animated duration - Add setEdgeInsets command to codegen spec, MapView class, and MapViewRef - iOS: CADisplayLink-driven animation for both Google Maps and Apple Maps - Android: animateCamera with duration for Google Maps - Add SetEdgeInsetsOptions interface with duration param - Update example to use command on detent change with spring-animated center pin --- .../src/main/java/com/luggmaps/LuggMapView.kt | 4 +- .../java/com/luggmaps/LuggMapViewManager.kt | 10 +++ .../com/luggmaps/core/GoogleMapProvider.kt | 10 ++- .../com/luggmaps/core/MapProviderDelegate.kt | 1 + example/bare/ios/Podfile.lock | 4 +- example/shared/src/Home.tsx | 65 ++++++++++++++----- example/shared/src/components/Map.tsx | 43 ++---------- ios/LuggMapView.mm | 10 +++ ios/core/AppleMapProvider.mm | 56 ++++++++++++++++ ios/core/GoogleMapProvider.mm | 62 +++++++++++++++++- ios/core/MapProviderDelegate.h | 3 + src/MapView.tsx | 12 +++- src/MapView.types.ts | 8 +++ src/MapView.web.tsx | 4 ++ src/fabric/LuggMapViewNativeComponent.ts | 10 ++- src/index.ts | 1 + 16 files changed, 240 insertions(+), 63 deletions(-) diff --git a/android/src/main/java/com/luggmaps/LuggMapView.kt b/android/src/main/java/com/luggmaps/LuggMapView.kt index ece4cb9..24e1190 100644 --- a/android/src/main/java/com/luggmaps/LuggMapView.kt +++ b/android/src/main/java/com/luggmaps/LuggMapView.kt @@ -220,9 +220,9 @@ class LuggMapView(private val reactContext: ThemedReactContext) : provider?.setTheme(value) } - fun setEdgeInsets(top: Int, left: Int, bottom: Int, right: Int) { + fun setEdgeInsets(top: Int, left: Int, bottom: Int, right: Int, duration: Int = 0) { edgeInsets = EdgeInsets(top, left, bottom, right) - provider?.setEdgeInsets(edgeInsets) + provider?.setEdgeInsets(edgeInsets, duration) } // endregion diff --git a/android/src/main/java/com/luggmaps/LuggMapViewManager.kt b/android/src/main/java/com/luggmaps/LuggMapViewManager.kt index d38d7e7..3501856 100644 --- a/android/src/main/java/com/luggmaps/LuggMapViewManager.kt +++ b/android/src/main/java/com/luggmaps/LuggMapViewManager.kt @@ -159,6 +159,16 @@ class LuggMapViewManager : view.moveCamera(latitude, longitude, zoom, duration.toInt()) } + override fun setEdgeInsets(view: LuggMapView, top: Double, left: Double, bottom: Double, right: Double, duration: Double) { + view.setEdgeInsets( + top.toFloat().dpToPx().toInt(), + left.toFloat().dpToPx().toInt(), + bottom.toFloat().dpToPx().toInt(), + right.toFloat().dpToPx().toInt(), + duration.toInt() + ) + } + override fun fitCoordinates( view: LuggMapView, coordinates: ReadableArray?, diff --git a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt index f38cc5b..21ff5c2 100644 --- a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +++ b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt @@ -209,6 +209,10 @@ class GoogleMapProvider(private val context: Context) : } override fun setEdgeInsets(edgeInsets: EdgeInsets) { + setEdgeInsets(edgeInsets, 0) + } + + override fun setEdgeInsets(edgeInsets: EdgeInsets, duration: Int) { val map = googleMap val oldInsets = this.edgeInsets this.edgeInsets = edgeInsets @@ -216,7 +220,11 @@ class GoogleMapProvider(private val context: Context) : if (map != null && oldInsets != edgeInsets) { val cameraUpdate = CameraUpdateFactory.newCameraPosition(map.cameraPosition) applyEdgeInsets() - map.moveCamera(cameraUpdate) + if (duration > 0) { + map.animateCamera(cameraUpdate, duration, null) + } else { + map.moveCamera(cameraUpdate) + } } else { applyEdgeInsets() } diff --git a/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt b/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt index 553acad..ce9ff85 100644 --- a/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +++ b/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt @@ -30,6 +30,7 @@ interface MapProvider { fun setMinZoom(zoom: Double) fun setMaxZoom(zoom: Double) fun setEdgeInsets(edgeInsets: EdgeInsets) + fun setEdgeInsets(edgeInsets: EdgeInsets, duration: Int) // Children fun addMarkerView(markerView: LuggMarkerView) diff --git a/example/bare/ios/Podfile.lock b/example/bare/ios/Podfile.lock index 96db141..0c75b36 100644 --- a/example/bare/ios/Podfile.lock +++ b/example/bare/ios/Podfile.lock @@ -11,7 +11,7 @@ PODS: - hermes-engine (0.14.0): - hermes-engine/Pre-built (= 0.14.0) - hermes-engine/Pre-built (0.14.0) - - LuggMaps (0.2.0-alpha.24): + - LuggMaps (0.2.0-alpha.27): - boost - DoubleConversion - fast_float @@ -3050,7 +3050,7 @@ SPEC CHECKSUMS: glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 GoogleMaps: 0608099d4870cac8754bdba9b6953db543432438 hermes-engine: 3515eff1a2de44b79dfa94a03d1adeed40f0dafe - LuggMaps: decd48fedf38073fcd53a74394624d5eaa763b2b + LuggMaps: 52b43077d9f8ca87c7c9c22771aa61fd93df5ae3 RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36 RCTRequired: f3540eee8094231581d40c5c6d41b0f170237a81 diff --git a/example/shared/src/Home.tsx b/example/shared/src/Home.tsx index 9d2c30f..aecd72e 100644 --- a/example/shared/src/Home.tsx +++ b/example/shared/src/Home.tsx @@ -13,15 +13,22 @@ import { type CameraEventPayload, } from '@lugg/maps'; import { - type TrueSheet, + TrueSheet, + type DetentChangeEvent, TrueSheetProvider, } from '@lodev09/react-native-true-sheet'; import { - ReanimatedTrueSheet, - ReanimatedTrueSheetProvider, - useReanimatedTrueSheet, -} from '@lodev09/react-native-true-sheet/reanimated'; -import { useDerivedValue } from 'react-native-reanimated'; + useSharedValue, + withSpring, + type WithSpringConfig, +} from 'react-native-reanimated'; + +const SPRING_CONFIG: WithSpringConfig = { + damping: 500, + stiffness: 1000, + mass: 3, + overshootClamping: true, +}; import { Button, Map } from './components'; import { randomFrom, randomLetter } from './utils'; @@ -43,11 +50,34 @@ function HomeContent() { const [markers, setMarkers] = useState(INITIAL_MARKERS); const [cameraPosition, setCameraPosition] = useState(); const [isIdle, setIsIdle] = useState(true); + const edgeInsetsBottom = useSharedValue(0); + + const handleMapReady = useCallback(() => { + const bottom = edgeInsetsBottom.value; + if (bottom > 0) { + mapRef.current?.setEdgeInsets({ top: 0, left: 0, bottom, right: 0 }); + } + }, [edgeInsetsBottom]); + + const handleSheetPresent = useCallback( + (event: DetentChangeEvent) => { + const bottom = screenHeight - event.nativeEvent.position; + edgeInsetsBottom.value = bottom; + mapRef.current?.setEdgeInsets({ top: 0, left: 0, bottom, right: 0 }); + }, + [screenHeight, edgeInsetsBottom] + ); - const { animatedPosition } = useReanimatedTrueSheet(); - - const animatedEdgeInsetsBottom = useDerivedValue( - () => screenHeight - animatedPosition.value + const handleDetentChange = useCallback( + (event: DetentChangeEvent) => { + const bottom = screenHeight - event.nativeEvent.position; + edgeInsetsBottom.value = withSpring(bottom, SPRING_CONFIG); + mapRef.current?.setEdgeInsets( + { top: 0, left: 0, bottom, right: 0 }, + { duration: 300 } + ); + }, + [screenHeight, edgeInsetsBottom] ); const handleCameraMove = useCallback( @@ -124,14 +154,15 @@ function HomeContent() { ref={mapRef} provider={provider} markers={markers} - animatedEdgeInsetsBottom={animatedEdgeInsetsBottom} + edgeInsetsBottom={edgeInsetsBottom} userLocationEnabled={locationPermission} + onReady={handleMapReady} onCameraMove={handleCameraMove} onCameraIdle={handleCameraIdle} /> )} - {cameraPosition ? ( @@ -187,7 +220,7 @@ function HomeContent() { } /> - + @@ -195,11 +228,7 @@ function HomeContent() { } export function Home() { - return ( - - - - ); + return ; } const styles = StyleSheet.create({ diff --git a/example/shared/src/components/Map.tsx b/example/shared/src/components/Map.tsx index 976d060..a898c74 100644 --- a/example/shared/src/components/Map.tsx +++ b/example/shared/src/components/Map.tsx @@ -1,5 +1,5 @@ import { forwardRef, useMemo, useState } from 'react'; -import { Platform, StyleSheet, View } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import { MapView, Marker, @@ -8,18 +8,10 @@ import { } from '@lugg/maps'; import type { NativeSyntheticEvent } from 'react-native'; import Animated, { - useAnimatedProps, - useAnimatedReaction, useAnimatedStyle, - useDerivedValue, type SharedValue, } from 'react-native-reanimated'; -const isWeb = Platform.OS === 'web'; -const AnimatedMapView = isWeb - ? MapView - : Animated.createAnimatedComponent(MapView); - import { MarkerIcon } from './MarkerIcon'; import { MarkerText } from './MarkerText'; import { MarkerImage } from './MarkerImage'; @@ -29,7 +21,7 @@ import { Route, smoothCoordinates } from './Route'; interface MapProps extends MapViewProps { markers: MarkerData[]; - animatedEdgeInsetsBottom?: SharedValue; + edgeInsetsBottom?: SharedValue; } const renderMarker = (marker: MarkerData) => { @@ -94,7 +86,7 @@ export const Map = forwardRef( { markers, edgeInsets, - animatedEdgeInsetsBottom, + edgeInsetsBottom, onCameraIdle, onCameraMove, ...props @@ -111,28 +103,8 @@ export const Map = forwardRef( [polylineCoordinates] ); - const animatedEdgeInsets = useDerivedValue(() => ({ - top: edgeInsets?.top ?? 0, - left: edgeInsets?.left ?? 0, - right: edgeInsets?.right ?? 0, - bottom: animatedEdgeInsetsBottom?.value ?? edgeInsets?.bottom ?? 0, - })); - - const [webEdgeInsets, setWebEdgeInsets] = useState(edgeInsets); - - useAnimatedReaction( - () => animatedEdgeInsets.value, - (value) => { - if (isWeb) setWebEdgeInsets(value); - } - ); - - const animatedProps = useAnimatedProps(() => ({ - edgeInsets: animatedEdgeInsets.value, - })); - const centerPinStyle = useAnimatedStyle(() => ({ - transform: [{ translateY: -animatedEdgeInsets.value.bottom / 2 }], + transform: [{ translateY: -(edgeInsetsBottom?.value ?? 0) / 2 }], })); const handleCameraMove = (e: NativeSyntheticEvent) => { @@ -146,14 +118,13 @@ export const Map = forwardRef( return ( - ( text="LO" color="#34A853" /> - + ); diff --git a/ios/LuggMapView.mm b/ios/LuggMapView.mm index 948b202..e704f3f 100644 --- a/ios/LuggMapView.mm +++ b/ios/LuggMapView.mm @@ -273,6 +273,16 @@ - (void)fitCoordinates:(NSArray *)coordinates duration:duration]; } +- (void)setEdgeInsets:(double)top + left:(double)left + bottom:(double)bottom + right:(double)right + duration:(double)duration { + UIEdgeInsets oldInsets = _edgeInsets; + _edgeInsets = UIEdgeInsetsMake(top, left, bottom, right); + [_provider setEdgeInsets:_edgeInsets oldEdgeInsets:oldInsets duration:duration]; +} + - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args { RCTLuggMapViewHandleCommand(self, commandName, args); } diff --git a/ios/core/AppleMapProvider.mm b/ios/core/AppleMapProvider.mm index de3aab2..d6a05e4 100644 --- a/ios/core/AppleMapProvider.mm +++ b/ios/core/AppleMapProvider.mm @@ -29,6 +29,13 @@ @implementation AppleMapProvider { double _minZoom; double _maxZoom; NSMapTable, LuggPolylineView *> *_overlayToPolylineMap; + + // Edge insets animation + CADisplayLink *_edgeInsetsDisplayLink; + UIEdgeInsets _edgeInsetsFrom; + UIEdgeInsets _edgeInsetsTo; + CFTimeInterval _edgeInsetsAnimationStart; + CFTimeInterval _edgeInsetsAnimationDuration; } @synthesize delegate = _delegate; @@ -76,6 +83,7 @@ - (void)initializeMapInView:(UIView *)wrapperView } - (void)destroy { + [self stopEdgeInsetsAnimation]; [_mapView removeFromSuperview]; _mapView = nil; _isMapReady = NO; @@ -151,6 +159,54 @@ - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets } } +- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets + oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets + duration:(double)duration { + [self stopEdgeInsetsAnimation]; + + if (duration > 0 && _mapView) { + _edgeInsetsFrom = oldEdgeInsets; + _edgeInsetsTo = edgeInsets; + _edgeInsetsAnimationDuration = duration / 1000.0; + _edgeInsetsAnimationStart = CACurrentMediaTime(); + + _edgeInsetsDisplayLink = + [CADisplayLink displayLinkWithTarget:self + selector:@selector(edgeInsetsAnimationTick:)]; + [_edgeInsetsDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] + forMode:NSRunLoopCommonModes]; + } else { + [self setEdgeInsets:edgeInsets oldEdgeInsets:oldEdgeInsets]; + } +} + +- (void)edgeInsetsAnimationTick:(CADisplayLink *)displayLink { + CFTimeInterval elapsed = CACurrentMediaTime() - _edgeInsetsAnimationStart; + CGFloat progress = MIN(elapsed / _edgeInsetsAnimationDuration, 1.0); + + // Ease out cubic + CGFloat t = 1.0 - (1.0 - progress) * (1.0 - progress) * (1.0 - progress); + + UIEdgeInsets current = UIEdgeInsetsMake( + _edgeInsetsFrom.top + (_edgeInsetsTo.top - _edgeInsetsFrom.top) * t, + _edgeInsetsFrom.left + (_edgeInsetsTo.left - _edgeInsetsFrom.left) * t, + _edgeInsetsFrom.bottom + + (_edgeInsetsTo.bottom - _edgeInsetsFrom.bottom) * t, + _edgeInsetsFrom.right + + (_edgeInsetsTo.right - _edgeInsetsFrom.right) * t); + + [self setEdgeInsets:current oldEdgeInsets:_mapView.layoutMargins]; + + if (progress >= 1.0) { + [self stopEdgeInsetsAnimation]; + } +} + +- (void)stopEdgeInsetsAnimation { + [_edgeInsetsDisplayLink invalidate]; + _edgeInsetsDisplayLink = nil; +} + - (CLLocationDistance)cameraDistanceForZoomLevel:(double)zoomLevel { return 128000000.0 / pow(2, zoomLevel); } diff --git a/ios/core/GoogleMapProvider.mm b/ios/core/GoogleMapProvider.mm index ac04992..a572567 100644 --- a/ios/core/GoogleMapProvider.mm +++ b/ios/core/GoogleMapProvider.mm @@ -19,6 +19,13 @@ @implementation GoogleMapProvider { NSMutableArray *_pendingMarkerViews; NSMutableArray *_pendingPolylineViews; NSMapTable *_polylineAnimators; + + // Edge insets animation + CADisplayLink *_edgeInsetsDisplayLink; + UIEdgeInsets _edgeInsetsFrom; + UIEdgeInsets _edgeInsetsTo; + CFTimeInterval _edgeInsetsAnimationStart; + CFTimeInterval _edgeInsetsAnimationDuration; } @synthesize delegate = _delegate; @@ -86,6 +93,7 @@ - (void)initializeMapInView:(UIView *)wrapperView } - (void)destroy { + [self stopEdgeInsetsAnimation]; [_pendingMarkerViews removeAllObjects]; [_pendingPolylineViews removeAllObjects]; [_polylineAnimators removeAllObjects]; @@ -155,10 +163,60 @@ - (void)setMaxZoom:(double)maxZoom { - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets { + [self setEdgeInsets:edgeInsets oldEdgeInsets:oldEdgeInsets duration:0]; +} + +- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets + oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets + duration:(double)duration { if (UIEdgeInsetsEqualToEdgeInsets(_edgeInsets, edgeInsets)) return; - _edgeInsets = edgeInsets; - _mapView.padding = edgeInsets; + + [self stopEdgeInsetsAnimation]; + + if (duration > 0 && _mapView) { + _edgeInsetsFrom = _edgeInsets; + _edgeInsetsTo = edgeInsets; + _edgeInsets = edgeInsets; + _edgeInsetsAnimationDuration = duration / 1000.0; + _edgeInsetsAnimationStart = CACurrentMediaTime(); + + _edgeInsetsDisplayLink = + [CADisplayLink displayLinkWithTarget:self + selector:@selector(edgeInsetsAnimationTick:)]; + [_edgeInsetsDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] + forMode:NSRunLoopCommonModes]; + } else { + _edgeInsets = edgeInsets; + _mapView.padding = edgeInsets; + } +} + +- (void)edgeInsetsAnimationTick:(CADisplayLink *)displayLink { + CFTimeInterval elapsed = CACurrentMediaTime() - _edgeInsetsAnimationStart; + CGFloat progress = MIN(elapsed / _edgeInsetsAnimationDuration, 1.0); + + // Ease out cubic + CGFloat t = 1.0 - (1.0 - progress) * (1.0 - progress) * (1.0 - progress); + + UIEdgeInsets current = UIEdgeInsetsMake( + _edgeInsetsFrom.top + (_edgeInsetsTo.top - _edgeInsetsFrom.top) * t, + _edgeInsetsFrom.left + (_edgeInsetsTo.left - _edgeInsetsFrom.left) * t, + _edgeInsetsFrom.bottom + + (_edgeInsetsTo.bottom - _edgeInsetsFrom.bottom) * t, + _edgeInsetsFrom.right + + (_edgeInsetsTo.right - _edgeInsetsFrom.right) * t); + + _mapView.padding = current; + + if (progress >= 1.0) { + [self stopEdgeInsetsAnimation]; + } +} + +- (void)stopEdgeInsetsAnimation { + [_edgeInsetsDisplayLink invalidate]; + _edgeInsetsDisplayLink = nil; } #pragma mark - GMSMapViewDelegate diff --git a/ios/core/MapProviderDelegate.h b/ios/core/MapProviderDelegate.h index 9c52b26..9e571e0 100644 --- a/ios/core/MapProviderDelegate.h +++ b/ios/core/MapProviderDelegate.h @@ -39,6 +39,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)setMaxZoom:(double)maxZoom; - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets; +- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets + oldEdgeInsets:(UIEdgeInsets)oldEdgeInsets + duration:(double)duration; // Children - (void)addMarkerView:(LuggMarkerView *)markerView; diff --git a/src/MapView.tsx b/src/MapView.tsx index 0d250c5..2f12fe0 100644 --- a/src/MapView.tsx +++ b/src/MapView.tsx @@ -9,8 +9,9 @@ import type { MapViewRef, MoveCameraOptions, FitCoordinatesOptions, + SetEdgeInsetsOptions, } from './MapView.types'; -import type { Coordinate } from './types'; +import type { Coordinate, EdgeInsets } from './types'; export class MapView extends React.Component @@ -67,6 +68,15 @@ export class MapView ); } + setEdgeInsets(edgeInsets: EdgeInsets, options?: SetEdgeInsetsOptions) { + const ref = this.nativeRef.current; + if (!ref) return; + + const { top = 0, left = 0, bottom = 0, right = 0 } = edgeInsets; + const { duration = 0 } = options ?? {}; + Commands.setEdgeInsets(ref, top, left, bottom, right, duration); + } + render() { const { provider, diff --git a/src/MapView.types.ts b/src/MapView.types.ts index fb4089b..7bb7d2a 100644 --- a/src/MapView.types.ts +++ b/src/MapView.types.ts @@ -18,6 +18,13 @@ export interface FitCoordinatesOptions { duration?: number; } +/** + * Options for setting edge insets + */ +export interface SetEdgeInsetsOptions { + duration?: number; +} + /** * MapView ref methods */ @@ -27,6 +34,7 @@ export interface MapViewRef { coordinates: Coordinate[], options?: FitCoordinatesOptions ): void; + setEdgeInsets(edgeInsets: EdgeInsets, options?: SetEdgeInsetsOptions): void; } /** diff --git a/src/MapView.web.tsx b/src/MapView.web.tsx index 59507e9..32178f1 100644 --- a/src/MapView.web.tsx +++ b/src/MapView.web.tsx @@ -209,6 +209,10 @@ export const MapView = forwardRef(function MapView( right: (edgeInsets?.right ?? 0) + (fitEdgeInsets?.right ?? 0), }); }, + + setEdgeInsets() { + // No-op on web — edgeInsets is handled via props + }, }), [map, initialZoom, edgeInsets, offsetCenter] ); diff --git a/src/fabric/LuggMapViewNativeComponent.ts b/src/fabric/LuggMapViewNativeComponent.ts index a9ed208..f49a6ba 100644 --- a/src/fabric/LuggMapViewNativeComponent.ts +++ b/src/fabric/LuggMapViewNativeComponent.ts @@ -77,10 +77,18 @@ interface NativeCommands { edgeInsetsRight: Double, duration: Double ) => void; + setEdgeInsets: ( + viewRef: React.ElementRef, + top: Double, + left: Double, + bottom: Double, + right: Double, + duration: Double + ) => void; } export const Commands = codegenNativeCommands({ - supportedCommands: ['moveCamera', 'fitCoordinates'], + supportedCommands: ['moveCamera', 'fitCoordinates', 'setEdgeInsets'], }); export default codegenNativeComponent( diff --git a/src/index.ts b/src/index.ts index 416ad9e..d2ea408 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ export type { MapViewRef, MoveCameraOptions, FitCoordinatesOptions, + SetEdgeInsetsOptions, CameraEventPayload, } from './MapView.types'; export type { From 731955bf33def5b42a3ea82961cfb0b475697aba Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 08:21:58 +0800 Subject: [PATCH 2/9] refactor: rename fitCoordinates edgeInsets param to padding --- example/shared/src/Home.tsx | 2 +- src/MapView.tsx | 4 ++-- src/MapView.types.ts | 2 +- src/MapView.web.tsx | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/shared/src/Home.tsx b/example/shared/src/Home.tsx index aecd72e..481cd59 100644 --- a/example/shared/src/Home.tsx +++ b/example/shared/src/Home.tsx @@ -133,7 +133,7 @@ function HomeContent() { const fitAllMarkers = () => { const coordinates = markers.map((m) => m.coordinate); mapRef.current?.fitCoordinates(coordinates, { - edgeInsets: { + padding: { top: 60, left: 40, right: 40, diff --git a/src/MapView.tsx b/src/MapView.tsx index 2f12fe0..3c826cf 100644 --- a/src/MapView.tsx +++ b/src/MapView.tsx @@ -48,8 +48,8 @@ export class MapView const first = coordinates[0]; if (!ref || !first) return; - const { edgeInsets, duration = -1 } = options ?? {}; - const { top = 0, left = 0, bottom = 0, right = 0 } = edgeInsets ?? {}; + const { padding, duration = -1 } = options ?? {}; + const { top = 0, left = 0, bottom = 0, right = 0 } = padding ?? {}; if (coordinates.length === 1) { const zoom = this.props.initialZoom ?? 10; diff --git a/src/MapView.types.ts b/src/MapView.types.ts index 7bb7d2a..9d8920c 100644 --- a/src/MapView.types.ts +++ b/src/MapView.types.ts @@ -14,7 +14,7 @@ export interface MoveCameraOptions { * Options for fitting coordinates in view */ export interface FitCoordinatesOptions { - edgeInsets?: EdgeInsets; + padding?: EdgeInsets; duration?: number; } diff --git a/src/MapView.web.tsx b/src/MapView.web.tsx index 32178f1..cda2844 100644 --- a/src/MapView.web.tsx +++ b/src/MapView.web.tsx @@ -190,7 +190,7 @@ export const MapView = forwardRef(function MapView( const first = coordinates[0]; if (!map || !first) return; - const { edgeInsets: fitEdgeInsets, duration = -1 } = options ?? {}; + const { padding: fitPadding, duration = -1 } = options ?? {}; if (coordinates.length === 1) { this.moveCamera(first, { zoom: initialZoom, duration }); @@ -203,10 +203,10 @@ export const MapView = forwardRef(function MapView( }); map.fitBounds(bounds, { - top: (edgeInsets?.top ?? 0) + (fitEdgeInsets?.top ?? 0), - left: (edgeInsets?.left ?? 0) + (fitEdgeInsets?.left ?? 0), - bottom: (edgeInsets?.bottom ?? 0) + (fitEdgeInsets?.bottom ?? 0), - right: (edgeInsets?.right ?? 0) + (fitEdgeInsets?.right ?? 0), + top: (edgeInsets?.top ?? 0) + (fitPadding?.top ?? 0), + left: (edgeInsets?.left ?? 0) + (fitPadding?.left ?? 0), + bottom: (edgeInsets?.bottom ?? 0) + (fitPadding?.bottom ?? 0), + right: (edgeInsets?.right ?? 0) + (fitPadding?.right ?? 0), }); }, From e8914789c9d626d7898d86452e4a04cef1d94fe4 Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 08:41:04 +0800 Subject: [PATCH 3/9] feat(web): implement setEdgeInsets command with duration support --- .../src/main/java/com/luggmaps/LuggMapView.kt | 8 ++- .../java/com/luggmaps/LuggMapViewManager.kt | 9 ++- ios/LuggMapView.mm | 4 +- ios/core/AppleMapProvider.mm | 6 +- ios/core/GoogleMapProvider.mm | 6 +- src/MapView.web.tsx | 64 ++++++++++++------- 6 files changed, 65 insertions(+), 32 deletions(-) diff --git a/android/src/main/java/com/luggmaps/LuggMapView.kt b/android/src/main/java/com/luggmaps/LuggMapView.kt index 24e1190..82a133c 100644 --- a/android/src/main/java/com/luggmaps/LuggMapView.kt +++ b/android/src/main/java/com/luggmaps/LuggMapView.kt @@ -220,7 +220,13 @@ class LuggMapView(private val reactContext: ThemedReactContext) : provider?.setTheme(value) } - fun setEdgeInsets(top: Int, left: Int, bottom: Int, right: Int, duration: Int = 0) { + fun setEdgeInsets( + top: Int, + left: Int, + bottom: Int, + right: Int, + duration: Int = 0 + ) { edgeInsets = EdgeInsets(top, left, bottom, right) provider?.setEdgeInsets(edgeInsets, duration) } diff --git a/android/src/main/java/com/luggmaps/LuggMapViewManager.kt b/android/src/main/java/com/luggmaps/LuggMapViewManager.kt index 3501856..2fd966e 100644 --- a/android/src/main/java/com/luggmaps/LuggMapViewManager.kt +++ b/android/src/main/java/com/luggmaps/LuggMapViewManager.kt @@ -159,7 +159,14 @@ class LuggMapViewManager : view.moveCamera(latitude, longitude, zoom, duration.toInt()) } - override fun setEdgeInsets(view: LuggMapView, top: Double, left: Double, bottom: Double, right: Double, duration: Double) { + override fun setEdgeInsets( + view: LuggMapView, + top: Double, + left: Double, + bottom: Double, + right: Double, + duration: Double + ) { view.setEdgeInsets( top.toFloat().dpToPx().toInt(), left.toFloat().dpToPx().toInt(), diff --git a/ios/LuggMapView.mm b/ios/LuggMapView.mm index e704f3f..45cc83e 100644 --- a/ios/LuggMapView.mm +++ b/ios/LuggMapView.mm @@ -280,7 +280,9 @@ - (void)setEdgeInsets:(double)top duration:(double)duration { UIEdgeInsets oldInsets = _edgeInsets; _edgeInsets = UIEdgeInsetsMake(top, left, bottom, right); - [_provider setEdgeInsets:_edgeInsets oldEdgeInsets:oldInsets duration:duration]; + [_provider setEdgeInsets:_edgeInsets + oldEdgeInsets:oldInsets + duration:duration]; } - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args { diff --git a/ios/core/AppleMapProvider.mm b/ios/core/AppleMapProvider.mm index d6a05e4..8d1de12 100644 --- a/ios/core/AppleMapProvider.mm +++ b/ios/core/AppleMapProvider.mm @@ -170,9 +170,9 @@ - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets _edgeInsetsAnimationDuration = duration / 1000.0; _edgeInsetsAnimationStart = CACurrentMediaTime(); - _edgeInsetsDisplayLink = - [CADisplayLink displayLinkWithTarget:self - selector:@selector(edgeInsetsAnimationTick:)]; + _edgeInsetsDisplayLink = [CADisplayLink + displayLinkWithTarget:self + selector:@selector(edgeInsetsAnimationTick:)]; [_edgeInsetsDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } else { diff --git a/ios/core/GoogleMapProvider.mm b/ios/core/GoogleMapProvider.mm index a572567..83ab352 100644 --- a/ios/core/GoogleMapProvider.mm +++ b/ios/core/GoogleMapProvider.mm @@ -181,9 +181,9 @@ - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets _edgeInsetsAnimationDuration = duration / 1000.0; _edgeInsetsAnimationStart = CACurrentMediaTime(); - _edgeInsetsDisplayLink = - [CADisplayLink displayLinkWithTarget:self - selector:@selector(edgeInsetsAnimationTick:)]; + _edgeInsetsDisplayLink = [CADisplayLink + displayLinkWithTarget:self + selector:@selector(edgeInsetsAnimationTick:)]; [_edgeInsetsDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } else { diff --git a/src/MapView.web.tsx b/src/MapView.web.tsx index cda2844..d99a3ee 100644 --- a/src/MapView.web.tsx +++ b/src/MapView.web.tsx @@ -25,9 +25,10 @@ import type { MapViewRef, MoveCameraOptions, FitCoordinatesOptions, + SetEdgeInsetsOptions, CameraEventPayload, } from './MapView.types'; -import type { Coordinate } from './types'; +import type { Coordinate, EdgeInsets } from './types'; const createSyntheticEvent = (nativeEvent: T): NativeSyntheticEvent => ({ @@ -160,6 +161,40 @@ export const MapView = forwardRef(function MapView( [map, edgeInsets] ); + const applyEdgeInsets = useCallback( + (newEdgeInsets: EdgeInsets, duration?: number) => { + if (!map) return; + + const prev = prevEdgeInsets.current; + const center = map.getCenter(); + const zoom = map.getZoom() ?? initialZoom; + + if (center) { + const logicalCenter = offsetCenter( + { latitude: center.lat(), longitude: center.lng() }, + zoom, + prev, + true + ); + const newCenter = offsetCenter( + { latitude: logicalCenter.lat, longitude: logicalCenter.lng }, + zoom, + newEdgeInsets, + false + ); + + if (duration === 0) { + map.moveCamera({ center: newCenter, zoom }); + } else { + map.panTo(newCenter); + } + } + + prevEdgeInsets.current = newEdgeInsets; + }, + [map, initialZoom, offsetCenter] + ); + useImperativeHandle( ref, () => ({ @@ -210,11 +245,11 @@ export const MapView = forwardRef(function MapView( }); }, - setEdgeInsets() { - // No-op on web — edgeInsets is handled via props + setEdgeInsets(newEdgeInsets: EdgeInsets, options?: SetEdgeInsetsOptions) { + applyEdgeInsets(newEdgeInsets, options?.duration); }, }), - [map, initialZoom, edgeInsets, offsetCenter] + [map, initialZoom, edgeInsets, offsetCenter, applyEdgeInsets] ); useEffect(() => { @@ -235,26 +270,9 @@ export const MapView = forwardRef(function MapView( prev?.right !== edgeInsets.right; if (changed) { - const center = map.getCenter(); - const zoom = map.getZoom() ?? initialZoom; - if (center) { - const logicalCenter = offsetCenter( - { latitude: center.lat(), longitude: center.lng() }, - zoom, - prev, - true - ); - const newCenter = offsetCenter( - { latitude: logicalCenter.lat, longitude: logicalCenter.lng }, - zoom, - edgeInsets, - false - ); - map.panTo(newCenter); - } - prevEdgeInsets.current = edgeInsets; + applyEdgeInsets(edgeInsets); } - }, [map, edgeInsets, initialZoom, offsetCenter]); + }, [map, edgeInsets, applyEdgeInsets]); const handleDragStart = () => { setIsDragging(true); From 02f88622649c9537184177baab2075db9223d4c7 Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 10:42:07 +0800 Subject: [PATCH 4/9] fix(web): fix offsetCenter on web --- src/MapView.web.tsx | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/MapView.web.tsx b/src/MapView.web.tsx index d99a3ee..dd13e2d 100644 --- a/src/MapView.web.tsx +++ b/src/MapView.web.tsx @@ -127,15 +127,9 @@ export const MapView = forwardRef(function MapView( const prevEdgeInsets = useRef(edgeInsets); const offsetCenter = useCallback( - ( - coord: Coordinate, - zoom: number, - edgeInsetsOverride?: typeof edgeInsets, - reverse = false - ) => { - const p = edgeInsetsOverride ?? edgeInsets; - const div = map?.getDiv(); - if (!p || !div) { + (coord: Coordinate, zoom: number, insets?: EdgeInsets, reverse = false) => { + const p = insets ?? prevEdgeInsets.current; + if (!p) { return { lat: coord.latitude, lng: coord.longitude }; } @@ -158,7 +152,7 @@ export const MapView = forwardRef(function MapView( return { lat, lng }; }, - [map, edgeInsets] + [] ); const applyEdgeInsets = useCallback( @@ -237,11 +231,12 @@ export const MapView = forwardRef(function MapView( bounds.extend({ lat: coord.latitude, lng: coord.longitude }); }); + const ei = prevEdgeInsets.current; map.fitBounds(bounds, { - top: (edgeInsets?.top ?? 0) + (fitPadding?.top ?? 0), - left: (edgeInsets?.left ?? 0) + (fitPadding?.left ?? 0), - bottom: (edgeInsets?.bottom ?? 0) + (fitPadding?.bottom ?? 0), - right: (edgeInsets?.right ?? 0) + (fitPadding?.right ?? 0), + top: (ei?.top ?? 0) + (fitPadding?.top ?? 0), + left: (ei?.left ?? 0) + (fitPadding?.left ?? 0), + bottom: (ei?.bottom ?? 0) + (fitPadding?.bottom ?? 0), + right: (ei?.right ?? 0) + (fitPadding?.right ?? 0), }); }, @@ -249,7 +244,7 @@ export const MapView = forwardRef(function MapView( applyEdgeInsets(newEdgeInsets, options?.duration); }, }), - [map, initialZoom, edgeInsets, offsetCenter, applyEdgeInsets] + [map, initialZoom, offsetCenter, applyEdgeInsets] ); useEffect(() => { From 108646a3733df5191c9ddd6c96c86ea805f3e360 Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 10:42:13 +0800 Subject: [PATCH 5/9] refactor(example): simplify Home --- example/shared/src/Home.tsx | 62 ++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/example/shared/src/Home.tsx b/example/shared/src/Home.tsx index 481cd59..18e11ce 100644 --- a/example/shared/src/Home.tsx +++ b/example/shared/src/Home.tsx @@ -20,6 +20,7 @@ import { import { useSharedValue, withSpring, + withTiming, type WithSpringConfig, } from 'react-native-reanimated'; @@ -40,7 +41,14 @@ import { } from './markers'; import { useLocationPermission } from './useLocationPermission'; -function HomeContent() { +const bottomEdgeInsets = (bottom: number) => ({ + top: 0, + left: 0, + bottom, + right: 0, +}); + +export function Home() { const mapRef = useRef(null); const sheetRef = useRef(null); const { height: screenHeight } = useWindowDimensions(); @@ -52,46 +60,46 @@ function HomeContent() { const [isIdle, setIsIdle] = useState(true); const edgeInsetsBottom = useSharedValue(0); + const getSheetBottom = useCallback( + (event: DetentChangeEvent) => + screenHeight - event.nativeEvent.position, + [screenHeight] + ); + const handleMapReady = useCallback(() => { const bottom = edgeInsetsBottom.value; if (bottom > 0) { - mapRef.current?.setEdgeInsets({ top: 0, left: 0, bottom, right: 0 }); + mapRef.current?.setEdgeInsets(bottomEdgeInsets(bottom)); } }, [edgeInsetsBottom]); const handleSheetPresent = useCallback( (event: DetentChangeEvent) => { - const bottom = screenHeight - event.nativeEvent.position; + const bottom = getSheetBottom(event); edgeInsetsBottom.value = bottom; - mapRef.current?.setEdgeInsets({ top: 0, left: 0, bottom, right: 0 }); + mapRef.current?.setEdgeInsets(bottomEdgeInsets(bottom)); }, - [screenHeight, edgeInsetsBottom] + [getSheetBottom, edgeInsetsBottom] ); const handleDetentChange = useCallback( (event: DetentChangeEvent) => { - const bottom = screenHeight - event.nativeEvent.position; - edgeInsetsBottom.value = withSpring(bottom, SPRING_CONFIG); - mapRef.current?.setEdgeInsets( - { top: 0, left: 0, bottom, right: 0 }, - { duration: 300 } - ); + const bottom = getSheetBottom(event); + edgeInsetsBottom.value = + Platform.OS === 'ios' + ? withSpring(bottom, SPRING_CONFIG) + : withTiming(bottom); + mapRef.current?.setEdgeInsets(bottomEdgeInsets(bottom), { + duration: 300, + }); }, - [screenHeight, edgeInsetsBottom] + [getSheetBottom, edgeInsetsBottom] ); - const handleCameraMove = useCallback( - (event: { nativeEvent: CameraEventPayload }) => { + const handleCameraEvent = useCallback( + (event: { nativeEvent: CameraEventPayload }, idle: boolean) => { setCameraPosition(event.nativeEvent); - setIsIdle(false); - }, - [] - ); - - const handleCameraIdle = useCallback( - (event: { nativeEvent: CameraEventPayload }) => { - setCameraPosition(event.nativeEvent); - setIsIdle(true); + setIsIdle(idle); }, [] ); @@ -157,8 +165,8 @@ function HomeContent() { edgeInsetsBottom={edgeInsetsBottom} userLocationEnabled={locationPermission} onReady={handleMapReady} - onCameraMove={handleCameraMove} - onCameraIdle={handleCameraIdle} + onCameraMove={(e) => handleCameraEvent(e, false)} + onCameraIdle={(e) => handleCameraEvent(e, true)} /> )} @@ -227,10 +235,6 @@ function HomeContent() { ); } -export function Home() { - return ; -} - const styles = StyleSheet.create({ container: { flex: 1 }, positionText: { From 9f8d870f2216c5dcbb8e930b256fe523877a1b42 Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 11:07:39 +0800 Subject: [PATCH 6/9] feat: default setEdgeInsets to animated --- .../src/main/java/com/luggmaps/core/GoogleMapProvider.kt | 8 ++++---- example/shared/src/Home.tsx | 4 +--- ios/core/AppleMapProvider.mm | 5 +++-- ios/core/GoogleMapProvider.mm | 5 +++-- src/MapView.tsx | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt index 21ff5c2..88066da 100644 --- a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +++ b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt @@ -220,10 +220,10 @@ class GoogleMapProvider(private val context: Context) : if (map != null && oldInsets != edgeInsets) { val cameraUpdate = CameraUpdateFactory.newCameraPosition(map.cameraPosition) applyEdgeInsets() - if (duration > 0) { - map.animateCamera(cameraUpdate, duration, null) - } else { - map.moveCamera(cameraUpdate) + when { + duration < 0 -> map.animateCamera(cameraUpdate) + duration > 0 -> map.animateCamera(cameraUpdate, duration, null) + else -> map.moveCamera(cameraUpdate) } } else { applyEdgeInsets() diff --git a/example/shared/src/Home.tsx b/example/shared/src/Home.tsx index 18e11ce..492ee3b 100644 --- a/example/shared/src/Home.tsx +++ b/example/shared/src/Home.tsx @@ -89,9 +89,7 @@ export function Home() { Platform.OS === 'ios' ? withSpring(bottom, SPRING_CONFIG) : withTiming(bottom); - mapRef.current?.setEdgeInsets(bottomEdgeInsets(bottom), { - duration: 300, - }); + mapRef.current?.setEdgeInsets(bottomEdgeInsets(bottom)); }, [getSheetBottom, edgeInsetsBottom] ); diff --git a/ios/core/AppleMapProvider.mm b/ios/core/AppleMapProvider.mm index 8d1de12..e01d711 100644 --- a/ios/core/AppleMapProvider.mm +++ b/ios/core/AppleMapProvider.mm @@ -164,10 +164,11 @@ - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets duration:(double)duration { [self stopEdgeInsetsAnimation]; - if (duration > 0 && _mapView) { + if (duration != 0 && _mapView) { + double actualDuration = duration < 0 ? 0.3 : duration / 1000.0; _edgeInsetsFrom = oldEdgeInsets; _edgeInsetsTo = edgeInsets; - _edgeInsetsAnimationDuration = duration / 1000.0; + _edgeInsetsAnimationDuration = actualDuration; _edgeInsetsAnimationStart = CACurrentMediaTime(); _edgeInsetsDisplayLink = [CADisplayLink diff --git a/ios/core/GoogleMapProvider.mm b/ios/core/GoogleMapProvider.mm index 83ab352..a0e19fe 100644 --- a/ios/core/GoogleMapProvider.mm +++ b/ios/core/GoogleMapProvider.mm @@ -174,11 +174,12 @@ - (void)setEdgeInsets:(UIEdgeInsets)edgeInsets [self stopEdgeInsetsAnimation]; - if (duration > 0 && _mapView) { + if (duration != 0 && _mapView) { + double actualDuration = duration < 0 ? 0.3 : duration / 1000.0; _edgeInsetsFrom = _edgeInsets; _edgeInsetsTo = edgeInsets; _edgeInsets = edgeInsets; - _edgeInsetsAnimationDuration = duration / 1000.0; + _edgeInsetsAnimationDuration = actualDuration; _edgeInsetsAnimationStart = CACurrentMediaTime(); _edgeInsetsDisplayLink = [CADisplayLink diff --git a/src/MapView.tsx b/src/MapView.tsx index 3c826cf..4120657 100644 --- a/src/MapView.tsx +++ b/src/MapView.tsx @@ -73,7 +73,7 @@ export class MapView if (!ref) return; const { top = 0, left = 0, bottom = 0, right = 0 } = edgeInsets; - const { duration = 0 } = options ?? {}; + const { duration = -1 } = options ?? {}; Commands.setEdgeInsets(ref, top, left, bottom, right, duration); } From f087f5a947f578089f241a64a94c5efe9920cbde Mon Sep 17 00:00:00 2001 From: lodev09 Date: Thu, 12 Feb 2026 11:30:45 +0800 Subject: [PATCH 7/9] feat: add AnimatedMap for animatedProps comparison --- .../com/luggmaps/core/GoogleMapProvider.kt | 11 +- example/shared/src/Home.tsx | 46 +++++--- example/shared/src/components/AnimatedMap.tsx | 109 ++++++++++++++++++ example/shared/src/components/Map.tsx | 68 +---------- example/shared/src/components/index.ts | 1 + example/shared/src/renderMarker.tsx | 69 +++++++++++ 6 files changed, 223 insertions(+), 81 deletions(-) create mode 100644 example/shared/src/components/AnimatedMap.tsx create mode 100644 example/shared/src/renderMarker.tsx diff --git a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt index 88066da..b043b76 100644 --- a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +++ b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt @@ -209,7 +209,16 @@ class GoogleMapProvider(private val context: Context) : } override fun setEdgeInsets(edgeInsets: EdgeInsets) { - setEdgeInsets(edgeInsets, 0) + val oldInsets = this.edgeInsets + this.edgeInsets = edgeInsets + applyEdgeInsets() + + val map = googleMap + if (map != null && oldInsets != edgeInsets) { + mapView?.post { + setEdgeInsets(edgeInsets, 0) + } + } } override fun setEdgeInsets(edgeInsets: EdgeInsets, duration: Int) { diff --git a/example/shared/src/Home.tsx b/example/shared/src/Home.tsx index 492ee3b..f40e73c 100644 --- a/example/shared/src/Home.tsx +++ b/example/shared/src/Home.tsx @@ -31,7 +31,7 @@ const SPRING_CONFIG: WithSpringConfig = { overshootClamping: true, }; -import { Button, Map } from './components'; +import { AnimatedMap, Button, Map } from './components'; import { randomFrom, randomLetter } from './utils'; import { MARKER_COLORS, @@ -55,6 +55,7 @@ export function Home() { const locationPermission = useLocationPermission(); const [provider, setProvider] = useState('apple'); const [showMap, setShowMap] = useState(true); + const [useAnimatedProps, setUseAnimatedProps] = useState(false); const [markers, setMarkers] = useState(INITIAL_MARKERS); const [cameraPosition, setCameraPosition] = useState(); const [isIdle, setIsIdle] = useState(true); @@ -154,19 +155,32 @@ export function Home() { - {showMap && ( - handleCameraEvent(e, false)} - onCameraIdle={(e) => handleCameraEvent(e, true)} - /> - )} + {showMap && + (useAnimatedProps ? ( + handleCameraEvent(e, false)} + onCameraIdle={(e) => handleCameraEvent(e, true)} + /> + ) : ( + handleCameraEvent(e, false)} + onCameraIdle={(e) => handleCameraEvent(e, true)} + /> + ))} (p === 'google' ? 'apple' : 'google')) } /> +