Animate marker on Google Maps route in React
Animating markers on Google Maps route in React can make the user’s experience more enjoyable and engaging. Google Maps API provides a way to animate the marker smoothly along the route. To achieve this, we can get the multiple coordinates on the routes, and then we can use the setPosition()
method to move the marker along the path.
Demo Application
Animate marker on Google Maps route in React
1. Project structure
- animate-marker-google-maps-route-react
- node_modules
- public
- index.html
- src
- App.js
- GMap.js
- index.css
- index.js
- package-lock.json
- package.json
- README.md
2. Package dependencies
Run the following command to install @googlemaps/js-api-loader npm package.
1 | npm i @googlemaps/js-api-loader |
You will find the version of the following packages in React application.
3. Implementation
Refer to the following files for implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | import React, { useEffect, useRef, useState } from 'react'; const GMap = () => { const googleMapRef = useRef(null); const [map, setMap] = useState(null); useEffect(() => { const googleMap = initGoogleMap(); setMap(googleMap); }, []); useEffect(() => { if (!map) return; const routeOptions = new window.google.maps.Polyline({ strokeOpacity: 0, icons: [{ icon: { path: "M 0,-0.1 0,0.1", strokeOpacity: 0.8, strokeColor: 'red', scale: 5, }, offset: "0", repeat: "10px", }], }); const directionsService = new window.google.maps.DirectionsService(); const directionsRenderer = new window.google.maps.DirectionsRenderer({ polylineOptions: routeOptions }); const haight = new window.google.maps.LatLng(37.7699298, -122.4469157); const oceanBeach = new window.google.maps.LatLng(37.7683909618184, -122.51089453697205); const request = { origin: haight, destination: oceanBeach, travelMode: 'WALKING' }; directionsService.route(request, function (response, status) { if (status == 'OK') { directionsRenderer.setDirections(response); directionsRenderer.setMap(map); moveMarkerOnRoute(map, response.routes[0].overview_path); } }); }, [map]) const initGoogleMap = () => { return new window.google.maps.Map(googleMapRef.current, { center: new window.google.maps.LatLng(37.7699298, -122.4469157), zoom: 12 }); } const moveMarkerOnRoute = async (map, pathCoords) => { const marker = new window.google.maps.Marker({ position: pathCoords[0], map, icon: { url: '/person-marker.png', scaledSize: new window.google.maps.Size(40, 40), }, optimized: false, zIndex: 99 }); for (let i = 0; i < pathCoords.length; i++) { await animatedMove(marker, marker.getPosition(), pathCoords[i], 0.05); } } const animatedMove = async (marker, moveFrom, moveTo, t, delta = 100) => { return new Promise(resolve => { const deltalat = (moveTo.lat() - moveFrom.lat()) / delta; const deltalng = (moveTo.lng() - moveFrom.lng()) / delta; let delay = 10 * t, count = 0; for (let i = 0; i < delta; i++) { (function (ind) { setTimeout( function () { let lat = marker.position.lat(); let lng = marker.position.lng(); lat += deltalat; lng += deltalng; marker.setPosition(new window.google.maps.LatLng(lat, lng)); count++ if (count === delta) { resolve(marker); } }, delay * ind ); })(i) } }) } return <div ref={googleMapRef} style={{ width: 600, height: 300 }} /> } export default GMap; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import React, { useState, useEffect } from 'react'; import { Loader } from '@googlemaps/js-api-loader'; import GMap from './GMap'; // API key of the google map const GOOGLE_MAP_API_KEY = '<YOUR_GOOGLE_MAP_API_KEY>'; const App = () => { const [loadMap, setLoadMap] = useState(false); useEffect(() => { const options = { apiKey: GOOGLE_MAP_API_KEY, version: "weekly", libraries: ['geometry'] }; new Loader(options).load().then(() => { setLoadMap(true); }).catch(e => { console.error('Sorry, something went wrong: Please try again later. Error:', e); }); }, []); return ( <div className="App"> <h4>Animate marker on Google Maps route in React - <a href="https://www.cluemediator.com">Clue Mediator</a></h4> {!loadMap ? <div>Loading...</div> : <GMap />} <br /> <small><b>Note:</b> In order to make it work, you have to set the YOUR_GOOGLE_MAP_API_KEY in App.js file. </small> </div> ); } export default App; |
4. Output
Run your application and check the output in the browser.
Live Demo
That’s it for today.
Thank you for reading. Happy Coding..!!