RGM

react google map
GitHub icon

React markers

Fast, rerendering of markers is not occured during move/zoom operation (if you dont update state on bounds, etc change events, see idle quote)

To add custom React marker on map, you need 2 controls Overlay and Marker.

Overlay is needed to place React components inside.

Marker is a wrapper around your component to pass lat, lng into Overlay in a type safe way wihout touching props of your component.

Each marker is rendered inside placeholder with { width:0; height:0; display: grid } style. This allows to select origin point of marker using only its own css place-self, align-self, justify-self properties. Also { position: absolute } on a holder allows everything if grid positioning is not enough.

To simplify markers positioning you can use debug propery of Overlay element. It will show exact origin point position.

See below how to use Overlay and Marker.

Also play with debug property to see how you can use css alignSelf , justifySelf, placeSelf properties to align different kind of markers. (For markers with "fun" shape use position:relative and css left, right properties)

debug property won't work in production builds.

// @flow
import * as React from 'react';
import { Map, Overlay, Marker } from 'rgm';
import { Flex, Box } from 'react-system';
import { useGoogleApiLoader } from '../dev-src/hooks';
import { Ratio, Checkbox, Select } from '../dev-src/controls';
// https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions
const MAP_OPTIONS = {
zoom: 9,
center: {
lat: 59.936,
lng: 30.314,
},
// disable cmd-zoom and 2 fingers zoom I personally dislike it
gestureHandling: 'greedy',
clickableIcons: false,
};
export default function MarkerPage() {
const api = useGoogleApiLoader();
const [debug, setDebug] = React.useState(true);
const [alignSelf, setAlignSelf] = React.useState('end');
const [justifySelf, setJustifySelf] = React.useState('center');
return (
<div>
<Flex p={3} alignItems="baseline">
<Checkbox id="debug" value={debug} onChange={setDebug}>
Debug
</Checkbox>
<Box width={'8px'} />
<Select
value={alignSelf}
onChange={setAlignSelf}
options={['start', 'center', 'end']}
/>
<Box width={'8px'} />
<Select
value={justifySelf}
onChange={setJustifySelf}
options={['start', 'center', 'end']}
/>
</Flex>
<Ratio value={3 / 4}>
{api && (
<Map api={api} options={MAP_OPTIONS}>
<Overlay debug={debug}>
<Marker lat={MAP_OPTIONS.center.lat} lng={MAP_OPTIONS.center.lng}>
<MarkerBottom
style={{
alignSelf,
justifySelf,
// easier to use placeSelf
}}
size={48}
color={'red'}
/>
</Marker>
<Marker
lat={MAP_OPTIONS.center.lat + 0.1}
lng={MAP_OPTIONS.center.lng + 0.3}
>
<MarkerCentered
style={{
alignSelf,
justifySelf,
}}
size={48}
color={'Fuchsia'}
/>
</Marker>
<Marker
lat={MAP_OPTIONS.center.lat - 0.1}
lng={MAP_OPTIONS.center.lng - 0.3}
>
<MarkerCorner
style={{
alignSelf,
justifySelf,
}}
size={48}
color={'OrangeRed'}
/>
</Marker>
</Overlay>
</Map>
)}
</Ratio>
</div>
);
}
const MarkerBottom = ({ size, color, style }) => (
<svg
style={style}
xmlns="http://www.w3.org/2000/svg"
height={size}
width={size}
viewBox="2 2 20 20"
fill={color}
>
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
<path d="M0 0h24v24H0z" fill="none" />
</svg>
);
const MarkerCentered = ({ size, color, style }) => (
<svg
style={style}
xmlns="http://www.w3.org/2000/svg"
height={size}
viewBox="0 0 24 24"
width={size}
fill={color}
>
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" />
</svg>
);
const MarkerCorner = ({ size, color, style }) => (
<svg
style={style}
xmlns="http://www.w3.org/2000/svg"
height={size}
viewBox="3 3 18 18"
width={size}
fill={color}
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M21 3L3 10.53v.98l6.84 2.65L12.48 21h.98L21 3z" />
</svg>
);
EXAMPLES ARE PROVIDED UNDER THE BEER-WARE LICENSE