Closed fzkhan19 closed 1 month ago
yep, I don't think something like that can be done with the vanilla DirectionsRenderer that comes with the Maps JavaScript API. I think the best choice for this would be the deck.gl TripsLayer (see also the demo here: https://deck.gl/examples/trips-layer).
For that you need to specify the points along the path together with timestamps and then animate the 'currentTime' value of the layer. If you don't have a 'true' timing reference you can use e.g. the relative distance along the path as timestamp.
That TripsLayer can then be added to the map with an interleaved overlay as shown here: https://visgl.github.io/react-google-maps/docs/guides/deckgl-integration#using-googlemapsoverlay
I tried to write the code, now i'm struggling to get it to animate
here's the code -
Directions.tsx:
"use client";
import {Color, Position} from "@deck.gl/core";
import {TripsLayer} from "@deck.gl/geo-layers";
import {GoogleMapsOverlay} from "@deck.gl/google-maps";
import {useMap, useMapsLibrary} from "@vis.gl/react-google-maps";
import {useEffect, useState} from "react";
const LOOP_LENGTH = 100;
type DataType = {
vendor: number;
path: Position[];
timestamps: number[];
};
export default function Directions({
directionServiceResponse,
}: {
directionServiceResponse: google.maps.DirectionsResult;
}) {
const map = useMap();
const routesLibrary = useMapsLibrary("routes");
const [directionsRenderer, setDirectionsRenderer] = useState<google.maps.DirectionsRenderer>();
const [routes, setRoutes] = useState<google.maps.DirectionsRoute[]>([]);
const selected = routes[0];
const leg = selected?.legs[0];
// Initialize directions service and renderer
useEffect(() => {
if (!routesLibrary || !map) return;
setDirectionsRenderer(new routesLibrary.DirectionsRenderer({map}));
}, [routesLibrary, map]);
// Assign direction response to renderer
useEffect(() => {
if (!directionsRenderer) return;
directionsRenderer.setDirections(directionServiceResponse);
setRoutes(directionServiceResponse.routes);
return () => directionsRenderer.setMap(null);
}, [directionsRenderer]);
// Update direction route
useEffect(() => {
if (!directionsRenderer) return;
directionsRenderer.setRouteIndex(0);
}, [directionsRenderer]);
// Initialize and animate TripsLayer
useEffect(() => {
if (!map || !leg) return;
const path = leg.steps.flatMap((step) =>
step.path.map((latlng) => [latlng.lng(), latlng.lat()]),
);
const timestamps = Array(path.length)
.fill(0)
.map((_, i) => i * 10); // Assuming each step takes 10 units of time
const data = [{vendor: 0, path, timestamps}];
console.log("DATA:::", data);
let currentTime = 0;
const props = {
id: "trips",
data,
getPath: (d: DataType) => d.path,
getTimestamps: (d: DataType) => d.timestamps,
getColor: [0, 255, 255] as Color,
opacity: 1,
widthMinPixels: 2,
trailLength: 180,
currentTime,
shadowEnabled: false,
};
const overlay = new GoogleMapsOverlay({interleaved: true});
const animate = () => {
currentTime = (currentTime + 1) % LOOP_LENGTH;
const tripsLayer = new TripsLayer({
...props,
currentTime,
});
overlay.setProps({
layers: [tripsLayer],
});
window.requestAnimationFrame(animate);
};
window.requestAnimationFrame(animate);
overlay.setMap(map);
return () => overlay.setMap(null);
}, [map, leg]);
if (!leg) return null;
return null;
}
RouteMap.tsx:
import {Map} from "@vis.gl/react-google-maps";
import {MAP_STYLE} from "@/constants";
import Directions from "./Directions";
export default function RouteMap({
directionServiceResponse,
}: {
directionServiceResponse: google.maps.DirectionsResult;
}) {
console.log(directionServiceResponse);
return (
<div>
<Map
className="m-0 h-full w-full rounded-md border-0 p-0"
clickableIcons={false}
controlSize={30}
defaultZoom={11}
disableDefaultUI={true}
fullscreenControl={true}
fullscreenControlOptions={{position: google.maps.ControlPosition.LEFT_TOP}}
gestureHandling={"greedy"}
mapId={"4f6dde3310be51d7"}
mapTypeControl={false}
streetViewControl={false}
styles={MAP_STYLE}
zoomControl={false}
>
<Directions directionServiceResponse={directionServiceResponse} />
</Map>
</div>
);
}
and the route is just sitting there
its working now there was some problem with loop length, now I'm having issues with default center and default zoom, they don't seem to be working
I believe the default behavior of the DirectionsRenderer is to fit the map to the bounds of the route. Also, what do you need the DirectionsRenderer for if you're rendering the Route using the TripsLayer?
Closing this since it's not a bugreport or feature request. Feel free to ask followup questions in our Discussions section.
Description
I want to animate the route displayed using direction renderer, I think deck.gl might help in this but im not sure how. i want a functionality same as show in this video: https://www.youtube.com/watch?v=H_BWRTf0d8g
Steps to Reproduce
none
Environment
Logs
No response