Skip to Content
ExamplesCamera Controls

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 degrees

Set Pitch (Tilt)

// Tilt the map camera to a specific pitch (0-60 degrees) await lazarilloMaps.setPitch('map-id', 30.0); // Tilt 30 degrees

Follow 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