@vis.gl/react-google-maps
Version:
React components and hooks for the Google Maps JavaScript API
86 lines (71 loc) • 2.34 kB
text/typescript
/* eslint-disable react-hooks/immutability -- Google Maps API objects are designed to be mutated */
import {useLayoutEffect} from 'react';
import {CameraStateRef3D} from './use-tracked-camera-state-ref-3d';
import {Map3DProps} from './index';
/**
* Converts a LatLngAltitude or LatLngAltitudeLiteral to a literal object.
*/
function toLatLngAltitudeLiteral(
value:
| google.maps.LatLngAltitude
| google.maps.LatLngAltitudeLiteral
| undefined
| null
): google.maps.LatLngAltitudeLiteral | null {
if (!value) return null;
// Check if it's a LatLngAltitude object with toJSON method
if ('toJSON' in value && typeof value.toJSON === 'function') {
return value.toJSON();
}
return value as google.maps.LatLngAltitudeLiteral;
}
/**
* Hook to update Map3D camera parameters when props change.
* Compares the current camera state with props and updates only when there are differences.
*
* @internal
*/
export function useMap3DCameraParams(
map3d: google.maps.maps3d.Map3DElement | null,
cameraStateRef: CameraStateRef3D,
props: Map3DProps
) {
const centerLiteral = toLatLngAltitudeLiteral(props.center);
const lat = centerLiteral?.lat ?? null;
const lng = centerLiteral?.lng ?? null;
const altitude = centerLiteral?.altitude ?? null;
const range = props.range ?? null;
const heading = props.heading ?? null;
const tilt = props.tilt ?? null;
const roll = props.roll ?? null;
// Runs on every render to sync controlled camera props with the map element
useLayoutEffect(() => {
if (!map3d) return;
const currentState = cameraStateRef.current;
if (
lat !== null &&
lng !== null &&
(currentState.center.lat !== lat ||
currentState.center.lng !== lng ||
(altitude !== null && currentState.center.altitude !== altitude))
) {
map3d.center = {
lat,
lng,
altitude: altitude ?? currentState.center.altitude ?? 0
};
}
if (range !== null && currentState.range !== range) {
map3d.range = range;
}
if (heading !== null && currentState.heading !== heading) {
map3d.heading = heading;
}
if (tilt !== null && currentState.tilt !== tilt) {
map3d.tilt = tilt;
}
if (roll !== null && currentState.roll !== roll) {
map3d.roll = roll;
}
});
}