Replace the Map
in calls to the InfoWindow#open
method with a StreetViewPanorama
In Google's documentation for the Maps JavaScript API on overlays within street view, it is noted that an InfoWindow
may be opened within a StreetViewPanorama
by passing the StreetViewPanorama
instead of a Map
when calling the open()
method.
In the @react-google-maps/api
codebase, the InfoWindow.tsx
file gets the Map
instance through React's Context API and uses it to open the InfoWindow
instance:
const map = useContext<google.maps.Map | null>(MapContext)
// ...
instance.open(map)
With that, we can import MapContext
and wrap our <InfoWindow>
with it to replace the map
with a StreetViewPanorama
instance, which we can get by using <StreetViewPanorama>
's onLoad
event.
import { createRoot } from "react-dom/client";
import {
useLoadScript,
GoogleMap,
StreetViewPanorama,
Marker,
InfoWindow,
MapContext,
} from "@react-google-maps/api";
import React, { useContext, useState } from "react";
function App() {
const astorPlace = { lat: 40.729884, lng: -73.990988 };
const [panorama, setPanorama] =
useState<google.maps.StreetViewPanorama | null>(null);
const markers = [
{
position: { lat: 40.730031, lng: -73.991428 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
title: "Cafe",
},
{
position: { lat: 40.729681, lng: -73.991138 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
title: "Bank",
},
{
position: { lat: 40.729559, lng: -73.990741 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
title: "Bus Stop",
},
];
function onPanoramaLoad(panorama: google.maps.StreetViewPanorama) {
panorama.setPosition(astorPlace);
panorama.setPov({
heading: 265,
pitch: 0,
});
panorama.setVisible(true);
setPanorama(panorama);
}
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
});
return (
<>
{isLoaded ? (
<GoogleMap center={astorPlace} zoom={18} id="map">
<StreetViewPanorama onLoad={onPanoramaLoad} />
{panorama ? (
// @ts-ignore
<MapContext.Provider value={panorama}>
{markers.map((marker) => (
<Marker key={marker.title} {...marker}>
<InfoWindow position={marker.position}>
<div
style={{
backgroundColor: "white",
opacity: 0.8,
}}
>
<h2>{marker.title}</h2>
</div>
</InfoWindow>
</Marker>
))}
</MapContext.Provider>
) : null}
</GoogleMap>
) : null}
{loadError ? <p>{loadError.message}</p> : null}
</>
);
}
createRoot(document.getElementById("app")!).render(<App />);
View this example live at CodeSandbox.
