The Camera component controls the perspective from which users view the map. It manages position (center coordinate), zoom level, bearing (heading), pitch (tilt), and padding.
Basic Usage
import { MapView , Camera } from '@rnmapbox/maps' ;
< MapView style = { { flex: 1 } } >
< Camera
centerCoordinate = { [ - 74.006 , 40.7128 ] } // [longitude, latitude]
zoomLevel = { 12 }
/>
</ MapView >
Camera Properties
Position and Zoom
< Camera
centerCoordinate = { [ - 122.4194 , 37.7749 ] } // San Francisco
zoomLevel = { 14 }
heading = { 90 } // Rotation in degrees (0-360)
pitch = { 60 } // Tilt in degrees (0-60)
/>
Property Type Description centerCoordinate[number, number]Map center as [longitude, latitude] zoomLevelnumberZoom level (0-22) headingnumberMap bearing/rotation (0-360°) pitchnumberMap tilt (0-60°)
Viewport Padding
Add padding to offset the camera center:
< Camera
centerCoordinate = { [ - 74.006 , 40.7128 ] }
zoomLevel = { 12 }
padding = { {
paddingTop: 100 ,
paddingBottom: 50 ,
paddingLeft: 20 ,
paddingRight: 20 ,
} }
/>
Padding is useful when UI elements overlay the map. The camera center will be offset so the geographic center appears in the unobstructed area.
Bounds
Fit the camera to a bounding box:
< Camera
bounds = { {
ne: [ - 73.9712 , 40.7831 ], // Northeast corner
sw: [ - 74.0402 , 40.6829 ], // Southwest corner
} }
padding = { {
paddingTop: 50 ,
paddingBottom: 50 ,
paddingLeft: 50 ,
paddingRight: 50 ,
} }
/>
Animation
Animation Modes
Control how the camera transitions between positions:
easeTo (Default)
flyTo
linearTo
moveTo
< Camera
centerCoordinate = { [ - 74.006 , 40.7128 ] }
zoomLevel = { 12 }
animationMode = "easeTo" // Smooth easing animation
animationDuration = { 2000 } // 2 seconds
/>
Mode Description Best For easeToSmooth easing transition Short distances flyToZooms out then in, like flying Long distances linearToLinear interpolation Controlled animations moveToInstant jump, no animation Immediate updates noneNo animation Static updates
Zoom Constraints
Limit the user’s ability to zoom:
< Camera
centerCoordinate = { [ - 74.006 , 40.7128 ] }
zoomLevel = { 12 }
minZoomLevel = { 10 } // Prevent zooming out past level 10
maxZoomLevel = { 16 } // Prevent zooming in past level 16
/>
Bounds Constraints
Restrict camera panning to a geographic area:
< Camera
centerCoordinate = { [ - 74.006 , 40.7128 ] }
zoomLevel = { 12 }
maxBounds = { {
ne: [ - 73.9 , 40.8 ], // Northeast boundary
sw: [ - 74.1 , 40.7 ], // Southwest boundary
} }
/>
User Location Tracking
Follow the user’s location with various tracking modes:
import { Camera , UserTrackingMode } from '@rnmapbox/maps' ;
< Camera
followUserLocation = { true }
followUserMode = { UserTrackingMode . Follow } // or FollowWithHeading, FollowWithCourse
followZoomLevel = { 16 }
followPitch = { 45 }
/>
Tracking Modes
Mode Behavior UserTrackingMode.FollowCenters on user location UserTrackingMode.FollowWithHeadingCenters and rotates map to device heading UserTrackingMode.FollowWithCourseCenters and rotates to movement direction
Imperative Camera Control
Use a ref to control the camera programmatically:
import { useRef } from 'react' ;
import { Camera } from '@rnmapbox/maps' ;
import type { CameraRef } from '@rnmapbox/maps' ;
const App = () => {
const cameraRef = useRef < CameraRef >( null );
const flyToNewYork = () => {
cameraRef . current ?. setCamera ({
centerCoordinate: [ - 74.006 , 40.7128 ],
zoomLevel: 14 ,
animationDuration: 2000 ,
});
};
const fitToBounds = () => {
cameraRef . current ?. fitBounds (
[ - 73.9712 , 40.7831 ], // Northeast
[ - 74.0402 , 40.6829 ], // Southwest
[ 50 , 50 , 50 , 50 ], // Padding [top, right, bottom, left]
1000 // Duration
);
};
return (
< MapView style = { { flex: 1 } } >
< Camera ref = { cameraRef } />
</ MapView >
);
};
Camera Methods
setCamera
Set multiple camera properties at once:
cameraRef . current ?. setCamera ({
centerCoordinate: [ - 122.4194 , 37.7749 ],
zoomLevel: 14 ,
heading: 90 ,
pitch: 60 ,
animationMode: 'flyTo' ,
animationDuration: 2000 ,
});
flyTo
Fly to a coordinate with realistic animation:
cameraRef . current ?. flyTo (
[ - 0.1276 , 51.5074 ], // London
3000 // Duration in ms
);
moveTo
Move to a coordinate with easing:
cameraRef . current ?. moveTo (
[ 2.3522 , 48.8566 ], // Paris
1000 // Duration in ms
);
zoomTo
Zoom to a specific level:
cameraRef . current ?. zoomTo (
16 , // Zoom level
500 // Duration in ms
);
fitBounds
Fit camera to bounds with padding:
cameraRef . current ?. fitBounds (
[ - 73.9712 , 40.7831 ], // Northeast
[ - 74.0402 , 40.6829 ], // Southwest
100 , // Uniform padding, or [top, right, bottom, left]
2000 // Duration
);
moveBy
Move camera by screen coordinates:
cameraRef . current ?. moveBy ({
x: 100 , // Pixels to move right
y: - 50 , // Pixels to move up
animationMode: 'easeTo' ,
animationDuration: 500 ,
});
scaleBy
Scale (zoom) around a point:
cameraRef . current ?. scaleBy ({
x: 200 , // Screen x coordinate
y: 300 , // Screen y coordinate
scaleFactor: 2.0 , // 2x zoom in (0.5 = zoom out)
animationMode: 'easeTo' ,
animationDuration: 300 ,
});
Default Settings
Provide fallback camera settings:
< Camera
defaultSettings = { {
centerCoordinate: [ - 74.006 , 40.7128 ],
zoomLevel: 10 ,
} }
// These will override defaults when set:
centerCoordinate = { userLocation }
zoomLevel = { 14 }
/>
Conditional Updates
Prevent unnecessary updates when map is not visible:
const [ mapVisible , setMapVisible ] = useState ( true );
< Camera
centerCoordinate = { [ - 74.006 , 40.7128 ] }
zoomLevel = { 12 }
allowUpdates = { mapVisible } // Only update when visible
/>
Complete Example
import { useState , useRef } from 'react' ;
import { View , Button , StyleSheet } from 'react-native' ;
import { MapView , Camera , UserTrackingMode } from '@rnmapbox/maps' ;
import type { CameraRef } from '@rnmapbox/maps' ;
const cities = {
nyc: [ - 74.006 , 40.7128 ],
sf: [ - 122.4194 , 37.7749 ],
london: [ - 0.1276 , 51.5074 ],
};
const App = () => {
const cameraRef = useRef < CameraRef >( null );
const [ following , setFollowing ] = useState ( false );
const flyToCity = ( coords : [ number , number ]) => {
setFollowing ( false );
cameraRef . current ?. flyTo ( coords , 2000 );
};
const toggleUserTracking = () => {
setFollowing ( ! following );
};
return (
< View style = { styles . container } >
< MapView style = { styles . map } >
< Camera
ref = { cameraRef }
defaultSettings = { {
centerCoordinate: cities . nyc ,
zoomLevel: 12 ,
} }
followUserLocation = { following }
followUserMode = { UserTrackingMode . FollowWithHeading }
followZoomLevel = { 16 }
animationMode = "flyTo"
animationDuration = { 2000 }
/>
</ MapView >
< View style = { styles . controls } >
< Button title = "NYC" onPress = { () => flyToCity ( cities . nyc ) } />
< Button title = "SF" onPress = { () => flyToCity ( cities . sf ) } />
< Button title = "London" onPress = { () => flyToCity ( cities . london ) } />
< Button
title = { following ? 'Stop Following' : 'Follow Me' }
onPress = { toggleUserTracking }
/>
</ View >
</ View >
);
};
const styles = StyleSheet . create ({
container: { flex: 1 },
map: { flex: 1 },
controls: {
position: 'absolute' ,
bottom: 50 ,
left: 0 ,
right: 0 ,
flexDirection: 'row' ,
justifyContent: 'space-around' ,
padding: 16 ,
},
});
export default App ;
Best Practices
Use appropriate animation modes : easeTo for nearby transitions, flyTo for long distances
Set bounds constraints : Prevent users from panning too far from your area of interest
Control frame rate : Set reasonable animationDuration values to maintain 60fps
Use allowUpdates : Disable camera updates when the map is not visible to save resources
MapView - Understanding the MapView component
Styling - Customize map appearance