urbica / react-map-gl

React Component Library for Mapbox GL JS
https://urbica.github.io/react-map-gl/
MIT License
416 stars 50 forks source link

Request for documentation: programmatic navigation #519

Closed braco closed 1 year ago

braco commented 1 year ago

It would be very helpful to have some documentation on manipulating the map from outside of the component. As in you click something outside of the map and the map zooms/pans as desired. This seems like a basic feature and it's not immediately obvious how to do it, unless I missed something.

stepankuzmin commented 1 year ago

You can manipulate the viewport state with setViewport, and that would be reflected in the map state, i.e., programmatic navigation.

const [viewport, setViewport] = useState({
  latitude: 37.78,
  longitude: -122.41,
  zoom: 11
});

<button onClick={() => { setViewport({ zoom: viewport.zoom + 1 }) }}>
  Zoom in
</button>

<MapGL
  style={{ width: '100%', height: '400px' }}
  mapStyle='mapbox://styles/mapbox/light-v9'
  accessToken={MAPBOX_ACCESS_TOKEN}
  latitude={viewport.latitude}
  longitude={viewport.longitude}
  zoom={viewport.zoom}
  onViewportChange={setViewport}
/>;

I'd appreciate a PR with such an example in the docs if you want to contribute.

braco commented 1 year ago

Thanks @stepankuzmin – and then probably a Provider to pass the setter around?

import React, { useState, useContext } from 'react';
const SetViewportProvider = createContext({});
export const useSetViewportProvider = () => useContext(SetViewportProvider);

<Map>
      <SetViewportProvider.Provider value={setViewport}>
             {children}
      </SetViewportProvider.Provider>
</Map>
import { useSetViewportProvider } from './Map';

const setter = useSetViewportProvider();
<button onClick={() => setter((oldstate) => ({ ...oldstate, zoom: 10 }))} />

It looks like changing the zoom level via this technique jumps in immediately without any easing/animation, despite AnimationOptions being set. Is this expected?

stepankuzmin commented 1 year ago

You can use an example for Viewport Change Methods from the map example page https://urbica.github.io/react-map-gl/#/Components/MapGL