import react, { useCallback, useState } from 'react'; import { atom, useAtom } from 'jotai'; import Handlers from './Handlers'; import Tile from './Tile'; import TiledLayer from './TiledLayer'; import { Point, TileFactory } from './types'; export interface MapProperties {} const initialCoordinateSystem = { zoom: 1, shift: { x: 0, y: 0 }, }; const coordinateSystemAtom = atom(initialCoordinateSystem); export interface Transformation { deltaShift: Point | null; deltaZoom: number | null; zoomCenter: Point | null; } export const relativeCoordinateSystemAtom = atom( null, (get, set, t: Transformation) => { const actualDeltaShift = t.deltaShift === null ? { x: 0, y: 0 } : t.deltaShift; const actualDeltaZoom = t.deltaZoom === null ? 1 : t.deltaZoom; const actualZoomCenter = t.zoomCenter === null ? { x: 0, y: 0 } : t.zoomCenter; const coordinateSystem = get(coordinateSystemAtom); var newCoordinateSystem = { shift: { x: coordinateSystem.shift.x + actualDeltaShift.x + (coordinateSystem.shift.x - actualZoomCenter.x) * (actualDeltaZoom - 1), y: coordinateSystem.shift.y + actualDeltaShift.y + (coordinateSystem.shift.y - actualZoomCenter.y) * (actualDeltaZoom - 1), }, zoom: coordinateSystem.zoom * actualDeltaZoom, }; set(coordinateSystemAtom, newCoordinateSystem); } ); /** * * @returns A Map component */ export const Map: react.FC = (props: MapProperties) => { const [coordinateSystem, setCoordinateSystem] = useAtom(coordinateSystemAtom); const simpleTileFactory: TileFactory = useCallback( (keyObject) => ( ), [] ); const viewPort = { topLeft: { x: Math.floor(-coordinateSystem.shift.x / coordinateSystem.zoom / 256), y: Math.floor(-coordinateSystem.shift.y / coordinateSystem.zoom / 256), }, bottomRight: { x: Math.ceil( (-coordinateSystem.shift.x + window.innerWidth) / coordinateSystem.zoom / 256 ), y: Math.ceil( (-coordinateSystem.shift.y + window.innerHeight) / coordinateSystem.zoom / 256 ), }, }; return ( <> ); }; export default Map;