animate_map_markers 0.0.3 copy "animate_map_markers: ^0.0.3" to clipboard
animate_map_markers: ^0.0.3 copied to clipboard

A Flutter package providing smooth scaling animations for Google Maps markers with an optional draggable sheet feature for dynamic user experiences.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:animate_map_markers/animate_map_markers.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

/// A sample Flutter app demonstrating how to use the `animate_map_markers` package.
///
/// This example displays a Google Map centered on Paris with a set of randomly placed
/// animated markers. Each marker scales smoothly using the `AnimatedMapMarkersWidget`.
///
/// Features:
/// - Random marker generation around a fixed location (Paris)
/// - Support for both PNG and SVG marker assets
/// - Smooth scale animation on markers
/// - An optional draggable bottom sheet that lists additional marker info
///
/// To run this example:
///  Ensure you have a valid Google Maps API key set up in your Android and iOS config.
///
/// Dependencies:
/// - `animate_map_markers`: for animated marker handling
/// - `google_maps_flutter`: for displaying Google Maps

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: HomePage(),
    );
  }
}

const int numberOfMarkers = 7;

class HomePage extends StatefulWidget {
  const HomePage({super.key});
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  /// Define the center of Paris
  final LatLng _parisCenter = LatLng(48.8566, 2.3522);

  final ValueNotifier<List<MarkerIconInfo>> scaledMarkerIconInfos =
      ValueNotifier<List<MarkerIconInfo>>([]);

  final List<String> markerAssets = [
    'assets/map_marker_1.png',
    'assets/map_marker_2.png',
    'assets/map_marker_3.png',
    'assets/map_marker_4.svg',
  ];

  /// The base size of the marker before scaling.
  static const minMarkerSize = Size(42.0, 48.0);

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    scaledMarkerIconInfos.value = _generateRandomMarkersIconInfos();
  }

  /// Function to generate random locations around Paris
  LatLng generateRandomLocation() {
    final random = Random();
    // Latitude and Longitude ranges around Paris (within a small radius of Paris)
    final double randomLat = 48.8566 +
        (random.nextDouble() * 0.1) -
        0.05; // random latitude near Paris
    final double randomLng = 2.3522 +
        (random.nextDouble() * 0.1) -
        0.05; // random longitude near Paris
    return LatLng(randomLat, randomLng);
  }

  final Random _random = Random();

  /// Function to add random markers on the map
  List<MarkerIconInfo> _generateRandomMarkersIconInfos() {
    final List<MarkerIconInfo> markerInfos = [];

    for (int i = 0; i < numberOfMarkers; i++) {
      final markerId = MarkerId('marker_$i');
      final String randomAsset =
          markerAssets[_random.nextInt(markerAssets.length)];
      final location = generateRandomLocation();
      final markerInfo = MarkerIconInfo(
          markerId: markerId,
          position: location,
          assetPath: randomAsset,
          minMarkerSize: minMarkerSize,
          scale: 1.7,
          curve: Curves.fastOutSlowIn,
          reverseCurve: Curves.easeInOut);

      markerInfos.add(markerInfo);
    }
    return markerInfos;
  }

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<List<MarkerIconInfo>>(
        valueListenable: scaledMarkerIconInfos,
        builder: (context, markerIconsInfos, _) {
          return AnimatedMapMarkersWidget(
            defaultCameraLocation: _parisCenter,
            zoomLevel: 12,
            scaledMarkerIconInfos: markerIconsInfos,
            showDraggableSheet: true,
            config: MarkerDraggableSheetConfig(
              showTopIndicator: false,
              boxShadow: [
                BoxShadow(
                  color: Colors.yellow,
                  blurRadius: 10,
                  spreadRadius: 1,
                  offset: Offset(0, 1),
                ),
              ],
              child: Column(
                children: List.generate(6, (_) => MarkerInfoCard()),
              ),
            ),
          );
        });
  }

  @override
  void dispose() {
    scaledMarkerIconInfos.dispose();
    super.dispose();
  }
}

class MarkerInfoCard extends StatelessWidget {
  const MarkerInfoCard({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.only(left: 30, right: 30),
        child: Column(
          children: [
            Row(
              children: [
                ClipRRect(
                  borderRadius: BorderRadius.circular(15.0),
                  child: Container(
                    color: Colors.black12,
                    height: 100,
                    width: 100,
                  ),
                ),
                SizedBox(width: 10),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      ClipRRect(
                        borderRadius: BorderRadius.circular(15.0),
                        child: Container(
                          color: Colors.black12,
                          height: 20,
                          width: 240,
                        ),
                      ),
                      SizedBox(height: 5),
                      ClipRRect(
                        borderRadius: BorderRadius.circular(15.0),
                        child: Container(
                          color: Colors.black12,
                          height: 20,
                          width: 180,
                        ),
                      ),
                      SizedBox(height: 50),
                    ],
                  ),
                )
              ],
            ),
            SizedBox(height: 10),
          ],
        ));
  }
}
7
likes
0
points
25
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package providing smooth scaling animations for Google Maps markers with an optional draggable sheet feature for dynamic user experiences.

Repository (GitHub)
View/report issues

Topics

#google-maps #map #animation

License

unknown (license)

Dependencies

flutter, flutter_svg, google_maps_flutter

More

Packages that depend on animate_map_markers