Moving the underlying map out of the slippy component and handling window resize events.
This commit is contained in:
parent
2207ae1652
commit
75b4bb2e2b
14
README.md
14
README.md
|
@ -1,3 +1,15 @@
|
||||||
# Dyomedea
|
# Dyomedea
|
||||||
|
|
||||||
Application de randonnée
|
## Hiking app.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
### Slippy
|
||||||
|
|
||||||
|
The viewport on the underlying map
|
||||||
|
|
||||||
|
### Map
|
||||||
|
|
||||||
|
The map itself (and its overlays)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,20 @@ import '@ionic/react/css/display.css';
|
||||||
/* Theme variables */
|
/* Theme variables */
|
||||||
import './theme/variables.css';
|
import './theme/variables.css';
|
||||||
|
|
||||||
import Map from './components/map';
|
import Map from './components/map/map';
|
||||||
|
import Slippy from './components/slippy';
|
||||||
|
import Layer from './components/slippy/layer';
|
||||||
|
import { Fragment } from 'react';
|
||||||
|
|
||||||
setupIonicReact();
|
setupIonicReact();
|
||||||
|
|
||||||
const App: React.FC = () => (
|
const App: React.FC = () => (
|
||||||
<IonApp>
|
<IonApp>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
<Slippy />
|
||||||
|
<Layer>
|
||||||
<Map />
|
<Map />
|
||||||
|
</Layer>
|
||||||
</Provider>
|
</Provider>
|
||||||
</IonApp>
|
</IonApp>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
import react from 'react';
|
|
||||||
import Slippy from './slippy/index';
|
|
||||||
|
|
||||||
const Map: react.FC<{}> = (props: {}) => {
|
|
||||||
return (
|
|
||||||
<Slippy>
|
|
||||||
<div>
|
|
||||||
<div style={{ height: '256px' }}>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11720/10052.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11721/10052.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11722/10052.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11723/10052.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ height: '256px' }}>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11720/10053.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11721/10053.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11722/10053.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11723/10053.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ height: '256px' }}>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11720/10054.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11721/10054.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11722/10054.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
alt=''
|
|
||||||
role='presentation'
|
|
||||||
src='https://tile.openstreetmap.org/14/11723/10054.png'
|
|
||||||
style={{ width: '256px', height: '256px', opacity: 1 }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Slippy>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Map;
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
import react, { useMemo, useEffect } from 'react';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { MapState, mapActions } from '../../store/map';
|
||||||
|
|
||||||
|
const Map: react.FC<{}> = (props: {}) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const mapState = useSelector((state: { map: MapState }) => state.map);
|
||||||
|
|
||||||
|
console.log(`mapState: ${JSON.stringify(mapState)}`);
|
||||||
|
|
||||||
|
const resizeHandler = () => {
|
||||||
|
dispatch(mapActions.resize());
|
||||||
|
};
|
||||||
|
const debouncedResizeHandler = useMemo(
|
||||||
|
() => _.debounce(resizeHandler, 500),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('resize', debouncedResizeHandler);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ height: '256px' }}>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11720/10052.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11721/10052.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11722/10052.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11723/10052.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ height: '256px' }}>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11720/10053.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11721/10053.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11722/10053.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11723/10053.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ height: '256px' }}>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11720/10054.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11721/10054.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11722/10054.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt=''
|
||||||
|
role='presentation'
|
||||||
|
src='https://tile.openstreetmap.org/14/11723/10054.png'
|
||||||
|
style={{ width: '256px', height: '256px', opacity: 1 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Map;
|
|
@ -1,12 +1,12 @@
|
||||||
import react from 'react';
|
import react from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
|
|
||||||
import MouseHandler from './mouse-handler';
|
import MouseHandler from './mouse-handler';
|
||||||
import Layer from './layer';
|
|
||||||
|
|
||||||
import '../../theme/slippy.css';
|
import '../../theme/slippy.css';
|
||||||
import SingleTouchHandler from './single-touch-handler';
|
import SingleTouchHandler from './single-touch-handler';
|
||||||
import DoubleTouchHandler from './double-touch-handler';
|
import DoubleTouchHandler from './double-touch-handler';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { MapState } from '../../store/map';
|
||||||
|
|
||||||
export interface Point {
|
export interface Point {
|
||||||
x: number;
|
x: number;
|
||||||
|
@ -24,19 +24,25 @@ export interface Scale {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ViewportProps {
|
const Slippy: react.FC<{}> = () => {
|
||||||
children: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Slippy: react.FC<ViewportProps> = (props: ViewportProps) => {
|
|
||||||
//console.log(`--- Rendering viewport, props: ${JSON.stringify(props)} ---`);
|
//console.log(`--- Rendering viewport, props: ${JSON.stringify(props)} ---`);
|
||||||
|
|
||||||
|
const viewport = useSelector(
|
||||||
|
(state: { map: MapState }) => state.map.viewport
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='slippy'>
|
<div className='slippy'>
|
||||||
<MouseHandler>
|
<MouseHandler>
|
||||||
<SingleTouchHandler>
|
<SingleTouchHandler>
|
||||||
<DoubleTouchHandler>
|
<DoubleTouchHandler>
|
||||||
<Layer>{props.children}</Layer>
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
width: viewport.width + 'px',
|
||||||
|
height: viewport.height + 'px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</DoubleTouchHandler>
|
</DoubleTouchHandler>
|
||||||
</SingleTouchHandler>
|
</SingleTouchHandler>
|
||||||
</MouseHandler>
|
</MouseHandler>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import react, { useCallback, useState } from 'react';
|
import react, { useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { configureStore } from '@reduxjs/toolkit';
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import slippyReducer from './slippy';
|
import slippyReducer from './slippy';
|
||||||
|
import mapReducer from './map';
|
||||||
|
|
||||||
const store = configureStore({
|
const store = configureStore({
|
||||||
reducer: { slippy: slippyReducer},
|
reducer: { slippy: slippyReducer, map: mapReducer },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
export interface MapState {
|
||||||
|
viewport: {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialMapState: MapState = {
|
||||||
|
viewport: {
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: window.innerHeight,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapSlice = createSlice({
|
||||||
|
name: 'map',
|
||||||
|
initialState: initialMapState,
|
||||||
|
reducers: {
|
||||||
|
resize: (state) => {
|
||||||
|
state.viewport.height = window.innerHeight;
|
||||||
|
state.viewport.width = window.innerWidth;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mapActions = mapSlice.actions;
|
||||||
|
|
||||||
|
export default mapSlice.reducer;
|
|
@ -4,8 +4,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.background img {
|
.huge {
|
||||||
width: 4032px;
|
position: fixed;
|
||||||
height: 2268px;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue