Guru Prasad mohapatra
Guru Prasad mohapatra

Reputation: 1969

How to add Animation for Google Maps Marker In Flutter?

Is there any way to animate marker on google maps in flutter like the native android ????

I'm using google_maps_flutter. It gives us a set of markers to set. But when am changing the coordinates of a marker it is simply being disappeared and appeared in the new place.

Upvotes: 3

Views: 5913

Answers (2)

Ryan Sneyd
Ryan Sneyd

Reputation: 199

Create an animation controller that tweens between two points lat lng points and updates the map directly. Use the animation value to update the marker's position. Change the speed of the animation using either the curve or duration parameters.

Tween Code taken from here: https://gist.github.com/avioli/a0b800d6a5ed053871ab4eec8f57c2da

newLocation is a latlng value that passes in the destination x, y values.

class MapSample extends StatefulWidget {
  final LatLng newLocation;
  const MapSample({super.key, required this.newLocation});

  @override
  State<MapSample> createState() => MapSampleState();
}

class MapSampleState extends State<MapSample>
    with SingleTickerProviderStateMixin {
  final Completer<GoogleMapController> _controller =
      Completer<GoogleMapController>();
  Map<String, Marker> markers = {};
  late AnimationController _animationController;
  late CurvedAnimation curvedAnimation;
  LatLng oldLocation = const LatLng(x, y);

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    curvedAnimation =
        CurvedAnimation(parent: _animationController, curve: Curves.ease);

    _animationController.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    if (oldLocation == widget.newLocation) {
      _animationController.reset();
    }
    Tween<LatLng> tween =
        LatLngTween(begin: oldLocation, end: widget.newLocation);
    Animation<LatLng> animation = tween.animate(curvedAnimation);
    _animationController.forward().then((value) async {
      oldLocation = widget.newLocation;
    });

    //print("${animation.value.latitude}, ${animation.value.longitude}");

    markers["location"] = Marker(
        markerId: const MarkerId("location"),
        position: LatLng(animation.value.latitude, animation.value.longitude));
    return GoogleMap(
      mapType: MapType.normal,
      markers: markers.values.toSet(),
      initialCameraPosition: CameraPosition(
        target: LatLng(x, y),
        zoom: 21,
      ),
      onMapCreated: (GoogleMapController controller) {
        _controller.complete(controller);
      },
    );
  }
}

class LatLngTween extends Tween<LatLng> {
  /// Creates a [LatLng] tween.
  ///
  /// The [begin] and [end] properties may be null; the null value
  /// is treated as an empty LatLng.
  LatLngTween({required LatLng begin, required LatLng end})
      : super(begin: begin, end: end);

  /// Returns the value this variable has at the given animation clock value.
  @override
  LatLng lerp(double t) {
    double lat, lng;
    if (begin == null) {
      lat = end!.latitude * t;
      lng = end!.longitude * t;
    } else if (end == null) {
      lat = begin!.latitude * (1.0 - t);
      lng = begin!.longitude * (1.0 - t);
    } else {
      print("${begin!.latitude}, ${end!.latitude}, $t");
      lat = lerpDouble(begin!.latitude, end!.latitude, t);
      lng = lerpDouble(begin!.longitude, end!.longitude, t);
    }
    return LatLng(lat, lng);
  }

  @protected
  double lerpDouble(double a, double b, double t) {
    return a + (b - a) * t;
  }
}

Upvotes: 0

Solution! https://pub.dev/packages/flutter_animarker It's works! You just need install one plugin.

Upvotes: 1

Related Questions