import _, { round } from 'lodash'; import react, { useState, useEffect, useMemo, useRef } from 'react'; import Tile from './tile'; import '../theme/map.css'; export const tileSize = 256; // cf https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_(JavaScript/ActionScript,_etc.) const lon2tile = (lon: number, zoom: number) => { const real = ((lon + 180) / 360) * Math.pow(2, zoom); const floor = Math.floor(real); return [floor, real - floor]; }; const lat2tile = (lat: number, zoom: number) => { const real = ((1 - Math.log( Math.tan((lat * Math.PI) / 180) + 1 / Math.cos((lat * Math.PI) / 180) ) / Math.PI) / 2) * Math.pow(2, zoom); const floor = Math.floor(real); return [floor, real - floor]; }; const Map: react.FC = () => { console.log('Log - Rendering '); const initialCenter: [number, number] = [43.57029965, 3.94242897]; const initialZoom: number = 17; const [center, setCenter] = useState(initialCenter); const [zoom, setZoom] = useState(initialZoom); const [dimensions, setDimensions] = useState({ height: window.innerHeight, width: window.innerWidth, }); const resizeHandler = () => { setDimensions({ height: window.innerHeight, width: window.innerWidth, }); }; const debouncedResizeHandler = useMemo( () => _.debounce(resizeHandler, 300), [dimensions, zoom, center] ); useEffect(() => { window.addEventListener('resize', debouncedResizeHandler); }, []); const nbTilesY = _.ceil(dimensions.height / tileSize) + 4; const nbTilesX = _.ceil(dimensions.width / tileSize) + 4; const [tileCenterY, reminderY] = lat2tile(center[0], zoom); const [tileCenterX, reminderX] = lon2tile(center[1], zoom); const firstTileY = tileCenterY - _.round(nbTilesY / 2); const firstTileX = tileCenterX - _.round(nbTilesX / 2); const locationY = (tileCenterY + reminderY - firstTileY) * tileSize; const locationX = (tileCenterX + reminderX - firstTileX) * tileSize; const targetLocationY = dimensions.height / 2; const targetLocationX = dimensions.width / 2; const deltaY = -targetLocationY + locationY; const deltaX = -targetLocationX + locationX; const [delta, setDelta] = useState({ X: deltaX, Y: deltaY }); const genericHandler = (event: any) => { console.log('Log - Event: ' + event.type); }; const initialMouseState = { down: false, starting: { x: -1, y: -1 }, }; const mouseState = useRef(initialMouseState); const mouseDownHandler = (event: any) => { event.preventDefault(); mouseState.current = { down: true, starting: { x: event.pageX, y: event.pageY }, }; genericHandler(event); }; const mouseUpHandler = (event: any) => { event.preventDefault(); console.log('Log - Up, now do something ! '); mouseState.current = initialMouseState; genericHandler(event); }; const mouseMoveHandler = (event: any) => { if (mouseState.current.down) { event.preventDefault(); console.log('Log - Moving...' + event.pageX); setDelta({ X: deltaX + mouseState.current.starting.x - event.pageX, Y: deltaY + mouseState.current.starting.y - event.pageY, }); genericHandler(event); } }; const debouncedMouseMoveHandler = useMemo( () => _.throttle(mouseMoveHandler, 100), [] ); const pointerDownHandler = (event: any) => { event.preventDefault(); console.log('PointerDown'); }; const pointerUpHandler = (event: any) => { event.preventDefault(); console.log('PointerUp'); }; const pointerMoveHandler = (event: any) => { event.preventDefault(); console.log('PointerMove'); }; return (
{_.range(nbTilesY).map((iy) => (
{_.range(nbTilesX).map((ix) => ( ))}
))}
); }; export default Map;