Camera Controls Example
This example demonstrates how to control the map camera using heading, bearing, and follow user location features.
🎮 Camera Control Methods
The Lazarillo Maps plugin provides several methods to control the map camera:
Set Bearing (Rotation)
// Rotate the map camera to a specific bearing (0-360 degrees)
await lazarilloMaps.setBearing('map-id', 90.0); // Rotate 90 degreesSet Pitch (Tilt)
// Tilt the map camera to a specific pitch (0-60 degrees)
await lazarilloMaps.setPitch('map-id', 30.0); // Tilt 30 degreesFollow User Location
// Follow user location with optional pitch and zoom
await lazarilloMaps.followUserLocation(
'map-id',
true, // Enable following
pitch: 45.0, // Optional pitch angle
zoom: 18.0, // Optional zoom level
);
// Stop following user location
await lazarilloMaps.followUserLocation('map-id', false);📱 Complete Example
Here’s a complete example showing all camera controls:
import 'package:flutter/material.dart';
import 'package:lazarillo_maps/lazarillo_maps.dart';
class CameraControlsExample extends StatefulWidget {
const CameraControlsExample({super.key});
@override
State<CameraControlsExample> createState() => _CameraControlsExampleState();
}
class _CameraControlsExampleState extends State<CameraControlsExample> {
final LazarilloMaps _lazarilloMaps = LazarilloMaps('your-api-key');
String? _mapId;
bool _isFollowingUser = false;
@override
void initState() {
super.initState();
_initializeMap();
}
Future<void> _initializeMap() async {
await _lazarilloMaps.initialize();
final mapWidget = _lazarilloMaps.getLazarilloMapWidget(
MapConfiguration(
parentPlaceId: 'your-place-id',
latitude: 40.7128,
longitude: -74.0060,
zoom: 15,
),
(mapId) {
setState(() {
_mapId = mapId;
});
print('Map ready: $mapId');
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Camera Controls Example'),
),
body: Column(
children: [
// Map Widget
Expanded(
child: _mapId != null
? _lazarilloMaps.getLazarilloMapWidget(
MapConfiguration(
parentPlaceId: 'your-place-id',
center: LatLng(40.7128, -74.0060),
zoom: 15.0,
),
(mapId) => print('Map ready: $mapId'),
)
: const Center(child: CircularProgressIndicator()),
),
// Camera Control Buttons
Container(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// Bearing Controls
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () => _setBearing(0),
child: const Text('North (0°)'),
),
ElevatedButton(
onPressed: () => _setBearing(90),
child: const Text('East (90°)'),
),
ElevatedButton(
onPressed: () => _setBearing(180),
child: const Text('South (180°)'),
),
ElevatedButton(
onPressed: () => _setBearing(270),
child: const Text('West (270°)'),
),
],
),
const SizedBox(height: 16),
// Pitch Controls
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () => _setPitch(0),
child: const Text('Flat (0°)'),
),
ElevatedButton(
onPressed: () => _setPitch(30),
child: const Text('Tilt (30°)'),
),
ElevatedButton(
onPressed: () => _setPitch(45),
child: const Text('Steep (45°)'),
),
ElevatedButton(
onPressed: () => _setPitch(60),
child: const Text('Vertical (60°)'),
),
],
),
const SizedBox(height: 16),
// Follow User Location
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: _toggleFollowUser,
style: ElevatedButton.styleFrom(
backgroundColor: _isFollowingUser ? Colors.green : Colors.blue,
),
child: Text(_isFollowingUser ? 'Stop Following' : 'Follow User'),
),
ElevatedButton(
onPressed: () => _followUserWithPitch(30),
child: const Text('Follow + Pitch'),
),
],
),
],
),
),
],
),
);
}
Future<void> _setBearing(double bearing) async {
if (_mapId != null) {
try {
await _lazarilloMaps.setBearing(_mapId!, bearing);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Bearing set to ${bearing}°')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error setting bearing: $e')),
);
}
}
}
Future<void> _setPitch(double pitch) async {
if (_mapId != null) {
try {
await _lazarilloMaps.setPitch(_mapId!, pitch);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Pitch set to ${pitch}°')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error setting pitch: $e')),
);
}
}
}
Future<void> _toggleFollowUser() async {
if (_mapId != null) {
try {
await _lazarilloMaps.followUserLocation(
_mapId!,
!_isFollowingUser,
);
setState(() {
_isFollowingUser = !_isFollowingUser;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(_isFollowingUser
? 'Now following user location'
: 'Stopped following user location'
),
),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error toggling follow: $e')),
);
}
}
}
Future<void> _followUserWithPitch(double pitch) async {
if (_mapId != null) {
try {
await _lazarilloMaps.followUserLocation(
_mapId!,
true,
pitch: pitch,
zoom: 18.0,
);
setState(() {
_isFollowingUser = true;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Following user with ${pitch}° pitch')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error following user: $e')),
);
}
}
}
}
## 🎯 Key Features
### Bearing Control
- **Range**: 0-360 degrees
- **Usage**: Rotate the map to face a specific direction
- **Example**: Set to 90° to face east
### Pitch Control
- **Range**: 0-60 degrees
- **Usage**: Tilt the map for a 3D perspective
- **Example**: Set to 30° for a tilted view
### Follow User Location
- **Features**: Automatically center on user location
- **Options**: Custom pitch and zoom levels
- **Usage**: Perfect for navigation apps
## ⚠️ Important Notes
1. **Map ID**: Always check that `_mapId` is not null before calling camera methods
2. **Error Handling**: Wrap camera control calls in try-catch blocks
3. **User Feedback**: Provide visual feedback for camera changes
4. **Performance**: Avoid rapid camera changes that might cause lag
## 🔧 Advanced Usage
### Smooth Camera Transitions
```dart
// Combine bearing and pitch for smooth transitions
await Future.wait([
lazarilloMaps.setBearing('map-id', 90.0),
lazarilloMaps.setPitch('map-id', 30.0),
]);Camera State Management
class CameraState {
double bearing = 0.0;
double pitch = 0.0;
bool isFollowingUser = false;
Future<void> resetCamera() async {
await lazarilloMaps.setBearing('map-id', 0.0);
await lazarilloMaps.setPitch('map-id', 0.0);
await lazarilloMaps.followUserLocation('map-id', false);
}
}This example demonstrates all the camera control features available in Lazarillo Maps Flutter.
Last updated on