diff --git a/package-lock.json b/package-lock.json
index 1b4341a..c449be2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"@types/react-router-dom": "^5.1.7",
"docuri": "^4.2.2",
"ionicons": "^6.0.3",
+ "jotai": "^1.8.6",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@@ -10584,6 +10585,55 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/jotai": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.8.6.tgz",
+ "integrity": "sha512-6JXNd2ewR6Ur0hGY0kRJebQ++p7lN/8kNdGNXv7XT11FDPxAtPN2XLM+m0w4bV22f1knQlG8ZpVLfY6BEGF+UQ==",
+ "engines": {
+ "node": ">=12.7.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "*",
+ "@babel/template": "*",
+ "@tanstack/query-core": "*",
+ "@urql/core": "*",
+ "immer": "*",
+ "optics-ts": "*",
+ "react": ">=16.8",
+ "valtio": "*",
+ "wonka": "*",
+ "xstate": "*"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@babel/template": {
+ "optional": true
+ },
+ "@tanstack/query-core": {
+ "optional": true
+ },
+ "@urql/core": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "optics-ts": {
+ "optional": true
+ },
+ "valtio": {
+ "optional": true
+ },
+ "wonka": {
+ "optional": true
+ },
+ "xstate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/js-sdsl": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz",
@@ -24804,6 +24854,12 @@
}
}
},
+ "jotai": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.8.6.tgz",
+ "integrity": "sha512-6JXNd2ewR6Ur0hGY0kRJebQ++p7lN/8kNdGNXv7XT11FDPxAtPN2XLM+m0w4bV22f1knQlG8ZpVLfY6BEGF+UQ==",
+ "requires": {}
+ },
"js-sdsl": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz",
diff --git a/package.json b/package.json
index eb90656..d123da6 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"@types/react-router-dom": "^5.1.7",
"docuri": "^4.2.2",
"ionicons": "^6.0.3",
+ "jotai": "^1.8.6",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
diff --git a/src/components/map/Handlers.test.tsx b/src/components/map/Handlers.test.tsx
index 8f32817..99298bb 100644
--- a/src/components/map/Handlers.test.tsx
+++ b/src/components/map/Handlers.test.tsx
@@ -8,7 +8,7 @@ describe('The Handlers component ', () => {
deltaZoom: number | null,
zoomCenter: Point | null
) => {};
- render();
+ render();
// screen.debug();
const handlers = screen.getByRole('presentation');
// screen.debug();
@@ -19,7 +19,7 @@ describe('The Handlers component ', () => {
/>
`);
});
- test('handle mouseDown / mouseMove events', () => {
+/* test('handle mouseDown / mouseMove events', () => {
var transformMapParams: any;
function transformMap(
deltaShift: Point | null,
@@ -242,5 +242,5 @@ Arguments [
null,
]
`);
- });
+ }); */
});
diff --git a/src/components/map/Handlers.tsx b/src/components/map/Handlers.tsx
index 5bc4c9e..76c725d 100644
--- a/src/components/map/Handlers.tsx
+++ b/src/components/map/Handlers.tsx
@@ -1,19 +1,12 @@
import react, { useRef, useState } from 'react';
+import { atom, useAtom } from 'jotai';
+
import { Point } from './types';
import './Handler.css';
import { handlersConfig } from './config';
+import { Transformation, relativeCoordinateSystemAtom } from './Map';
-export interface HandlersProperties {
- /**Transform the map:
- * * Shift the map by a number of pixel
- * * Multiply the zoom by deltaZoom around the zoomCenter
- * */
- transformMap: (
- deltaShift: Point | null,
- deltaZoom: number | null,
- zoomCenter: Point | null
- ) => void;
-}
+export interface HandlersProperties {}
/**
*
* @param props
@@ -29,6 +22,8 @@ export interface HandlersProperties {
export const Handlers: react.FC = (
props: HandlersProperties
) => {
+ const [, transformMap] = useAtom(relativeCoordinateSystemAtom);
+
const genericHandler = (event: any) => {
// console.log(`Log - Event: ${event.type}`);
// if (event.clientX !== undefined) {
@@ -84,14 +79,14 @@ export const Handlers: react.FC = (
) {
genericHandler(event);
if (mouseState.current.down) {
- props.transformMap(
- {
+ transformMap({
+ deltaShift: {
x: event.clientX - mouseState.current.starting.x,
y: event.clientY - mouseState.current.starting.y,
},
- null,
- null
- );
+ deltaZoom: null,
+ zoomCenter: null,
+ });
mouseState.current = {
down: true,
starting: {
@@ -112,9 +107,13 @@ export const Handlers: react.FC = (
const doubleClickHandler = (event: any) => {
genericHandler(event);
- props.transformMap(null, Math.SQRT2, {
- x: event.clientX,
- y: event.clientY,
+ transformMap({
+ deltaShift: null,
+ deltaZoom: Math.SQRT2,
+ zoomCenter: {
+ x: event.clientX,
+ y: event.clientY,
+ },
});
};
@@ -137,9 +136,13 @@ export const Handlers: react.FC = (
Date.now() - wheelState.current.timestamp >
handlersConfig.wheelThrottleDelay
) {
- props.transformMap(null, event.deltaY < 0 ? Math.SQRT2 : Math.SQRT1_2, {
- x: event.clientX,
- y: event.clientY,
+ transformMap({
+ deltaShift: null,
+ deltaZoom: event.deltaY < 0 ? Math.SQRT2 : Math.SQRT1_2,
+ zoomCenter: {
+ x: event.clientX,
+ y: event.clientY,
+ },
});
wheelState.current = {
timestamp: Date.now(),
@@ -238,17 +241,17 @@ export const Handlers: react.FC = (
x: (event.touches[0].screenX + event.touches[1].screenX) / 2,
y: (event.touches[0].screenY + event.touches[1].screenY) / 2,
};
- props.transformMap(
- {
+ transformMap({
+ deltaShift: {
x: currentCenter.x - previousCenter.x,
y: currentCenter.y - previousCenter.y,
},
- factor,
- {
+ deltaZoom: factor,
+ zoomCenter: {
x: currentCenter.x - previousCenter.x,
y: currentCenter.y - previousCenter.y,
- }
- );
+ },
+ });
}
} else if (
touchState.current.state === 'pointer' &&
@@ -257,14 +260,14 @@ export const Handlers: react.FC = (
) {
if (event.touches.length === 1) {
genericHandler(event);
- props.transformMap(
- {
+ transformMap({
+ deltaShift: {
x: event.touches[0].screenX - touchState.current.touches[0].x,
y: event.touches[0].screenY - touchState.current.touches[0].y,
},
- null,
- null
- );
+ deltaZoom: null,
+ zoomCenter: null,
+ });
touchState.current = {
state: 'pointer',
touches: [
diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx
index b97ce21..4951dff 100644
--- a/src/components/map/Map.tsx
+++ b/src/components/map/Map.tsx
@@ -1,4 +1,6 @@
import react, { useCallback, useState } from 'react';
+import { atom, useAtom } from 'jotai';
+
import Handlers from './Handlers';
import Tile from './Tile';
import TiledLayer from './TiledLayer';
@@ -6,33 +8,28 @@ import { Point, TileFactory } from './types';
export interface MapProperties {}
-/**
- *
- * @returns A Map component
- */
-export const Map: react.FC = (props: MapProperties) => {
- const [coordinateSystem, setCoordinateSystem] = useState({
- zoom: 1,
- shift: { x: 0, y: 0 },
- });
+const initialCoordinateSystem = {
+ zoom: 1,
+ shift: { x: 0, y: 0 },
+};
- const simpleTileFactory: TileFactory = useCallback(
- (keyObject) => (
-
- ),
- []
- );
+const coordinateSystemAtom = atom(initialCoordinateSystem);
- const transformMap = (
- deltaShift: Point | null,
- deltaZoom: number | null,
- zoomCenter: Point | null
- ) => {
- const actualDeltaShift = deltaShift === null ? { x: 0, y: 0 } : deltaShift;
- const actualDeltaZoom = deltaZoom === null ? 1 : deltaZoom;
- const actualZoomCenter = zoomCenter === null ? { x: 0, y: 0 } : zoomCenter;
+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:
@@ -48,8 +45,25 @@ export const Map: react.FC = (props: MapProperties) => {
},
zoom: coordinateSystem.zoom * actualDeltaZoom,
};
- setCoordinateSystem(newCoordinateSystem);
- };
+ 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: {
@@ -72,7 +86,7 @@ export const Map: react.FC = (props: MapProperties) => {
return (
<>
-
+