Implement camera controls and expose MapHandle API in MapView
This commit is contained in:
@@ -29,5 +29,26 @@ export default function App() {
|
||||
}
|
||||
```
|
||||
|
||||
## Camera Controls 🔧
|
||||
|
||||
This package exposes a small imperative `MapHandle` API via `ref` on `MapView`. Use it to animate the camera or fit bounds.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
const mapRef = useRef<MapHandle | null>(null);
|
||||
mapRef.current?.flyTo({ latitude: 37.78825, longitude: -122.4324 });
|
||||
mapRef.current?.fitBounds({ latitude: 37.809, longitude: -122.410 }, { latitude: 37.779, longitude: -122.450 });
|
||||
```
|
||||
|
||||
Available methods:
|
||||
|
||||
- `animateToRegion(region, duration?)` — animate to a region.
|
||||
- `animateCamera(camera, options?)` — animate using camera properties.
|
||||
- `flyTo(coordinate, duration?)` — quick helper that animates to a small region around `coordinate`.
|
||||
- `fitBounds(northEast, southWest, options?)` — fit the two coordinates with optional `edgePadding`.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
- This package delegates to `react-native-maps` for platform implementations. Follow `react-native-maps` docs for iOS/Android setup (Google Maps API key, pods, manifest permissions).
|
||||
|
||||
@@ -1,10 +1,78 @@
|
||||
import React from 'react';
|
||||
import RNMapView, { MapViewProps as RNMapViewProps } from 'react-native-maps';
|
||||
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||
import RNMapView, { MapViewProps as RNMapViewProps, Camera, Region, LatLng } from 'react-native-maps';
|
||||
|
||||
export type MapProps = RNMapViewProps;
|
||||
|
||||
const MapView: React.FC<MapProps> = (props) => {
|
||||
return <RNMapView {...props}>{props.children}</RNMapView>;
|
||||
export type MapHandle = {
|
||||
animateToRegion: (region: Region, duration?: number) => void;
|
||||
animateCamera: (camera: Partial<Camera>, options?: { duration?: number }) => void;
|
||||
flyTo: (coordinate: LatLng, duration?: number) => void;
|
||||
fitBounds: (
|
||||
northEast: LatLng,
|
||||
southWest: LatLng,
|
||||
options?: { edgePadding?: { top: number; left: number; bottom: number; right: number }; animated?: boolean }
|
||||
) => void;
|
||||
getCamera?: () => Promise<Camera | undefined>;
|
||||
};
|
||||
|
||||
const MapView = forwardRef<MapHandle, MapProps>((props, ref) => {
|
||||
const mapRef = useRef<RNMapView | null>(null);
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
animateToRegion(region: Region, duration = 500) {
|
||||
if (mapRef.current?.animateToRegion) {
|
||||
mapRef.current.animateToRegion(region, duration);
|
||||
}
|
||||
},
|
||||
animateCamera(camera: Partial<Camera>, options) {
|
||||
if (mapRef.current?.animateCamera) {
|
||||
mapRef.current.animateCamera(camera, options);
|
||||
}
|
||||
},
|
||||
flyTo(coordinate: LatLng, duration = 800) {
|
||||
if (mapRef.current?.animateToRegion) {
|
||||
const region: Region = {
|
||||
latitude: coordinate.latitude,
|
||||
longitude: coordinate.longitude,
|
||||
latitudeDelta: 0.01,
|
||||
longitudeDelta: 0.01,
|
||||
};
|
||||
mapRef.current.animateToRegion(region, duration);
|
||||
}
|
||||
},
|
||||
fitBounds(
|
||||
northEast: LatLng,
|
||||
southWest: LatLng,
|
||||
options = { edgePadding: { top: 20, left: 20, bottom: 20, right: 20 }, animated: true }
|
||||
) {
|
||||
if (mapRef.current?.fitToCoordinates) {
|
||||
mapRef.current.fitToCoordinates([northEast, southWest], {
|
||||
edgePadding: options.edgePadding,
|
||||
animated: options.animated,
|
||||
});
|
||||
}
|
||||
},
|
||||
async getCamera() {
|
||||
if (mapRef.current?.getCamera) {
|
||||
try {
|
||||
return await mapRef.current.getCamera();
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<RNMapView ref={mapRef} {...props}>
|
||||
{props.children}
|
||||
</RNMapView>
|
||||
);
|
||||
});
|
||||
|
||||
export default MapView;
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as MapView } from './MapView';
|
||||
export type { MapHandle } from './MapView';
|
||||
export { Marker, Polyline, PROVIDER_GOOGLE } from 'react-native-maps';
|
||||
|
||||
Reference in New Issue
Block a user