Using atomWithHash to enable back/forward actions.
This commit is contained in:
parent
e1583846ed
commit
fe9cc6437d
56
src/App.tsx
56
src/App.tsx
|
@ -22,32 +22,46 @@ import '@ionic/react/css/display.css';
|
||||||
import './theme/variables.css';
|
import './theme/variables.css';
|
||||||
import LiveMap from './components/map/LiveMap';
|
import LiveMap from './components/map/LiveMap';
|
||||||
|
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { atomWithHash } from 'jotai/utils';
|
||||||
|
import { MapScope } from './components/map/types';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
setupIonicReact();
|
setupIonicReact();
|
||||||
|
|
||||||
|
const initialScope: MapScope = {
|
||||||
|
center: { lat: -37.8403508, lon: 77.5539501 },
|
||||||
|
zoom: 13,
|
||||||
|
tileProvider: 'osm',
|
||||||
|
};
|
||||||
|
const scopeAtom = atomWithHash('scope', initialScope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns The root app component
|
* @returns The root app component
|
||||||
*/
|
*/
|
||||||
const App: React.FC = () => (
|
const App: React.FC = () => {
|
||||||
<IonApp>
|
const [scope, setScope] = useAtom(scopeAtom);
|
||||||
<IonReactRouter>
|
|
||||||
<IonRouterOutlet>
|
console.log(`App, scope: ${JSON.stringify(scope)}`);
|
||||||
<Route exact path='/home'>
|
return (
|
||||||
<LiveMap
|
<IonApp>
|
||||||
scope={{
|
<IonReactRouter>
|
||||||
center: { lat: -37.8403508, lon: 77.5539501 },
|
<IonRouterOutlet>
|
||||||
zoom: 13,
|
<Route exact path='/home'>
|
||||||
tileProvider: 'osm',
|
<LiveMap
|
||||||
}}
|
scope={scope}
|
||||||
numberOfTiledLayers={5}
|
setScope={debounce(setScope, 1000)}
|
||||||
/>
|
numberOfTiledLayers={5}
|
||||||
</Route>
|
/>
|
||||||
<Route exact path='/'>
|
</Route>
|
||||||
<Redirect to='/home' />
|
<Route exact path='/'>
|
||||||
</Route>
|
<Redirect to='/home' />
|
||||||
</IonRouterOutlet>
|
</Route>
|
||||||
</IonReactRouter>
|
</IonRouterOutlet>
|
||||||
</IonApp>
|
</IonReactRouter>
|
||||||
);
|
</IonApp>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import react, { useState } from 'react';
|
import react, { useEffect, useState } from 'react';
|
||||||
import { MapScope, Point } from './types';
|
import { MapScope, Point } from './types';
|
||||||
import Map from './Map';
|
import Map from './Map';
|
||||||
import Handlers from './Handlers';
|
import Handlers from './Handlers';
|
||||||
|
@ -31,26 +31,33 @@ export interface Transformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LiveMapProperties {
|
export interface LiveMapProperties {
|
||||||
|
/** The initial map's scope */
|
||||||
scope: MapScope;
|
scope: MapScope;
|
||||||
|
/** The number of tiled layers (default to 1) */
|
||||||
numberOfTiledLayers?: number;
|
numberOfTiledLayers?: number;
|
||||||
|
/** If provided, a function to call when the scope is updated. */
|
||||||
|
setScope?: (scope: MapScope) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param props
|
* @param props
|
||||||
* @returns A `<LiveMap>` component.
|
* @returns A `<LiveMap>` component.
|
||||||
*
|
*
|
||||||
* A `<LiveMap>` is a wrapper around a {@link components/map/Map!Map} component which updates the `<Map>`'s scope according to user's mouse, wheel and touch events.
|
* A `<LiveMap>` is a wrapper around a {@link components/map/Map!Map} component which updates the `<Map>`'s scope according to user's mouse, wheel and touch events.
|
||||||
*
|
*
|
||||||
* To do so, `<LiveMap>` embeds a `<Map>` component together with a {@link components/map/Handlers!Handlers} component which listens to user's event.
|
* To do so, `<LiveMap>` embeds a `<Map>` component together with a {@link components/map/Handlers!Handlers} component which listens to user's event.
|
||||||
*
|
*
|
||||||
* The main task of `<LiveMap>` components is thus to translate {@link Transformation}s delivered by `<Handler>` in pixels into geographical coordinates.
|
* The main task of `<LiveMap>` components is thus to translate {@link Transformation}s delivered by `<Handler>` in pixels into geographical coordinates.
|
||||||
*/
|
*/
|
||||||
export const LiveMap: react.FC<LiveMapProperties> = (
|
export const LiveMap: react.FC<LiveMapProperties> = (
|
||||||
props: LiveMapProperties
|
props: LiveMapProperties
|
||||||
) => {
|
) => {
|
||||||
const [scope, setScope] = useState(props.scope);
|
const [scope, setScope] = useState(props.scope);
|
||||||
// console.log(`LiveMap rendering: ${JSON.stringify(scope)}`);
|
useEffect(() => {
|
||||||
|
setScope(props.scope);
|
||||||
|
}, [props.scope]);
|
||||||
|
console.log(`LiveMap rendering: ${JSON.stringify(scope)}`);
|
||||||
const transform = (t: Transformation) => {
|
const transform = (t: Transformation) => {
|
||||||
const deltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom;
|
const deltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom;
|
||||||
const deltaZoomLevel = Math.log2(deltaZoom);
|
const deltaZoomLevel = Math.log2(deltaZoom);
|
||||||
|
@ -114,6 +121,9 @@ export const LiveMap: react.FC<LiveMapProperties> = (
|
||||||
// }, delta lon: ${newScope.center.lon - scope.center.lon}`
|
// }, delta lon: ${newScope.center.lon - scope.center.lon}`
|
||||||
// );
|
// );
|
||||||
setScope(newScope);
|
setScope(newScope);
|
||||||
|
if (props.setScope !== undefined) {
|
||||||
|
props.setScope(newScope);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Reference in New Issue