react-three-map 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +17 -7
  2. package/dist/cjs/main.js.js +1 -0
  3. package/dist/es/main.js.mjs +5 -0
  4. package/dist/es/main.js.mjs.map +1 -0
  5. package/dist/es/main.js10.mjs +40 -0
  6. package/dist/es/main.js10.mjs.map +1 -0
  7. package/dist/es/main.js11.mjs +13 -0
  8. package/dist/es/main.js11.mjs.map +1 -0
  9. package/dist/es/main.js12.mjs +13 -0
  10. package/dist/es/main.js12.mjs.map +1 -0
  11. package/dist/es/main.js13.mjs +31 -0
  12. package/dist/es/main.js13.mjs.map +1 -0
  13. package/dist/es/main.js14.mjs +13 -0
  14. package/dist/es/main.js14.mjs.map +1 -0
  15. package/dist/es/main.js15.mjs +15 -0
  16. package/dist/es/main.js15.mjs.map +1 -0
  17. package/dist/es/main.js16.mjs +14 -0
  18. package/dist/es/main.js16.mjs.map +1 -0
  19. package/dist/es/main.js17.mjs +56 -0
  20. package/dist/es/main.js17.mjs.map +1 -0
  21. package/dist/es/main.js18.mjs +9 -0
  22. package/dist/es/main.js18.mjs.map +1 -0
  23. package/dist/es/main.js19.mjs +320 -0
  24. package/dist/es/main.js19.mjs.map +1 -0
  25. package/dist/es/main.js2.mjs +40 -0
  26. package/dist/es/main.js2.mjs.map +1 -0
  27. package/dist/es/main.js20.mjs +72 -0
  28. package/dist/es/main.js20.mjs.map +1 -0
  29. package/dist/es/main.js21.mjs +6 -0
  30. package/dist/es/main.js21.mjs.map +1 -0
  31. package/dist/es/main.js22.mjs +19 -0
  32. package/dist/es/main.js22.mjs.map +1 -0
  33. package/dist/es/main.js23.mjs +14 -0
  34. package/dist/es/main.js23.mjs.map +1 -0
  35. package/dist/es/main.js24.mjs +34 -0
  36. package/dist/es/main.js24.mjs.map +1 -0
  37. package/dist/es/main.js25.mjs +15 -0
  38. package/dist/es/main.js25.mjs.map +1 -0
  39. package/dist/es/main.js26.mjs +8 -0
  40. package/dist/es/main.js26.mjs.map +1 -0
  41. package/dist/es/main.js27.mjs +41 -0
  42. package/dist/es/main.js27.mjs.map +1 -0
  43. package/dist/es/main.js28.mjs +26 -0
  44. package/dist/es/main.js28.mjs.map +1 -0
  45. package/dist/es/main.js3.mjs +21 -0
  46. package/dist/es/main.js3.mjs.map +1 -0
  47. package/dist/es/main.js4.mjs +11 -0
  48. package/dist/es/main.js4.mjs.map +1 -0
  49. package/dist/es/main.js5.mjs +53 -0
  50. package/dist/es/main.js5.mjs.map +1 -0
  51. package/dist/es/main.js6.mjs +16 -0
  52. package/dist/es/main.js6.mjs.map +1 -0
  53. package/dist/es/main.js7.mjs +62 -0
  54. package/dist/es/main.js7.mjs.map +1 -0
  55. package/dist/es/main.js8.mjs +58 -0
  56. package/dist/es/main.js8.mjs.map +1 -0
  57. package/dist/es/main.js9.mjs +49 -0
  58. package/dist/es/main.js9.mjs.map +1 -0
  59. package/dist/es/vite.svg +1 -0
  60. package/index.html +13 -0
  61. package/package.json +16 -15
  62. package/src/canvas/canvas.tsx +49 -0
  63. package/src/canvas/coords-to-matrix.ts +19 -0
  64. package/src/canvas/create-events.ts +73 -0
  65. package/src/canvas/state-ref.ts +9 -0
  66. package/src/canvas/use-function.ts +10 -0
  67. package/src/canvas/use-on-add.ts +67 -0
  68. package/src/canvas/use-render.ts +27 -0
  69. package/src/main.ts +1 -0
  70. package/src/stories/canvas.stories.tsx +28 -0
  71. package/src/stories/my-scene.tsx +83 -0
  72. package/src/stories/no-map.stories.tsx +12 -0
  73. package/src/vite-env.d.ts +1 -0
  74. package/tsconfig.json +25 -0
  75. package/tsconfig.node.json +10 -0
  76. package/dist/my-lib.es.js +0 -1538
  77. package/dist/my-lib.umd.js +0 -27
  78. /package/dist/{vite.svg → cjs/vite.svg} +0 -0
@@ -0,0 +1,73 @@
1
+ import { Events, RenderProps, RootState, createEvents as createFiberEvents } from "@react-three/fiber";
2
+ import { UseBoundStore } from "zustand";
3
+
4
+ type DomEvent = PointerEvent | MouseEvent | WheelEvent;
5
+
6
+ const DOM_EVENTS = {
7
+ onClick: ["click", false],
8
+ onContextMenu: ["contextmenu", false],
9
+ onDoubleClick: ["dblclick", false],
10
+ onWheel: ["wheel", true],
11
+ onPointerDown: ["pointerdown", true],
12
+ onPointerUp: ["pointerup", true],
13
+ onPointerLeave: ["pointerleave", true],
14
+ onPointerMove: ["pointermove", true],
15
+ onPointerCancel: ["pointercancel", true],
16
+ onLostPointerCapture: ["lostpointercapture", true],
17
+ } as const;
18
+
19
+ /** ThreeLayer event manager for MapLibre and Mapbox */
20
+ export function createEvents() : RenderProps<HTMLCanvasElement>["events"] {
21
+ return (store: UseBoundStore<RootState>) => {
22
+ const { handlePointer } = createFiberEvents(store);
23
+ return {
24
+ priority: 1,
25
+ enabled: true,
26
+ compute(event: DomEvent, state: RootState) {
27
+ state.size.width = state.gl.domElement.width;
28
+ state.size.height = state.gl.domElement.height;
29
+ state.pointer.x = (event.offsetX / (state.size.width / window.devicePixelRatio)) * 2 - 1;
30
+ state.pointer.y = 1 - (event.offsetY / (state.size.height / window.devicePixelRatio)) * 2;
31
+ state.raycaster.camera = state.camera;
32
+ state.raycaster.ray.origin.setScalar(0).applyMatrix4(state.camera.projectionMatrixInverse);
33
+ state.raycaster.ray.direction
34
+ .set(state.pointer.x, state.pointer.y, 1)
35
+ .applyMatrix4(state.camera.projectionMatrixInverse)
36
+ .sub(state.raycaster.ray.origin)
37
+ .normalize();
38
+ },
39
+ connected: undefined,
40
+ handlers: Object.keys(DOM_EVENTS).reduce(
41
+ (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
42
+ {}
43
+ ) as unknown as Events,
44
+ update: () => {
45
+ const { events, internal } = store.getState();
46
+ if (internal.lastEvent?.current && events.handlers) {
47
+ events.handlers.onPointerMove(internal.lastEvent.current);
48
+ }
49
+ },
50
+ connect: (target: HTMLElement) => {
51
+ const { set, events } = store.getState();
52
+ events.disconnect?.();
53
+ set((state) => ({ events: { ...state.events, connected: target } }));
54
+ Object.entries(events.handlers ?? []).forEach(([name, event]) => {
55
+ const [eventName, passive] = DOM_EVENTS[name as keyof typeof DOM_EVENTS];
56
+ target.addEventListener(eventName, event, { passive });
57
+ });
58
+ },
59
+ disconnect: () => {
60
+ const { set, events } = store.getState();
61
+ if (events.connected) {
62
+ Object.entries(events.handlers ?? []).forEach(([name, event]) => {
63
+ if (events && events.connected instanceof HTMLElement) {
64
+ const [eventName] = DOM_EVENTS[name as keyof typeof DOM_EVENTS];
65
+ events.connected.removeEventListener(eventName, event);
66
+ }
67
+ });
68
+ set((state) => ({ events: { ...state.events, connected: undefined } }));
69
+ }
70
+ },
71
+ };
72
+ };
73
+ }
@@ -0,0 +1,9 @@
1
+ import { ReconcilerRoot, RootState } from "@react-three/fiber";
2
+ import { MutableRefObject } from "react";
3
+ import { MapInstance } from "react-map-gl";
4
+
5
+ export type StateRef = MutableRefObject<{
6
+ map: MapInstance;
7
+ root: ReconcilerRoot<HTMLCanvasElement>;
8
+ state?: RootState;
9
+ } | undefined>
@@ -0,0 +1,10 @@
1
+ import { useCallback, useRef } from 'react';
2
+
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ export const useFunction = <T extends (...args: any[]) => any>(callback: T): T => {
5
+ const callbackRef = useRef(callback);
6
+ callbackRef.current = callback;
7
+ return useCallback((...args: any[]) => {
8
+ return callbackRef.current(...args);
9
+ }, []) as T;
10
+ };
@@ -0,0 +1,67 @@
1
+ import { RenderProps, createRoot } from "@react-three/fiber";
2
+ import { MapInstance } from "react-map-gl";
3
+ import { createEvents } from "./create-events";
4
+ import { StateRef } from "./state-ref";
5
+ import { useFunction } from "./use-function";
6
+ import { useState } from "react";
7
+
8
+ export function useOnAdd (ref: StateRef, renderProps: RenderProps<HTMLCanvasElement>) {
9
+
10
+ const [mounted, setMounted] = useState(false);
11
+
12
+ const onAdd = useFunction((map: MapInstance, gl: WebGLRenderingContext)=>{
13
+
14
+ const canvas = map.getCanvas();
15
+ const root = createRoot(canvas);
16
+ root.configure({
17
+ frameloop: "never",
18
+ dpr: window.devicePixelRatio,
19
+ shadows: true,
20
+ events: createEvents(),
21
+ ...renderProps,
22
+ gl: {
23
+ context: gl,
24
+ depth: true,
25
+ autoClear: false,
26
+ antialias: true,
27
+ ...renderProps?.gl,
28
+ },
29
+ onCreated: (state) => {
30
+ ref.current = {
31
+ state,
32
+ map,
33
+ root,
34
+ }
35
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
36
+ state.gl.forceContextLoss = () => { };
37
+ },
38
+ camera: {
39
+ matrixAutoUpdate: false,
40
+ },
41
+ size: {
42
+ width: canvas.clientWidth,
43
+ height: canvas.clientHeight,
44
+ top: 0,
45
+ left: 0,
46
+ ...renderProps?.size,
47
+ },
48
+ });
49
+
50
+ ref.current = {
51
+ map,
52
+ root,
53
+ }
54
+
55
+ setTimeout(()=>setMounted(true));
56
+
57
+ })
58
+
59
+ const onRemove = useFunction(()=>{
60
+ setTimeout(()=>{
61
+ if(!ref.current) return;
62
+ ref.current.root.unmount();
63
+ })
64
+ })
65
+
66
+ return {onAdd, onRemove, mounted};
67
+ }
@@ -0,0 +1,27 @@
1
+ import { Matrix4 } from "three";
2
+ import { StateRef } from "./state-ref";
3
+ import { useFunction } from "./use-function";
4
+ import { useMap } from "react-map-gl/maplibre";
5
+
6
+ export function useRender(
7
+ m4: Matrix4, ref: StateRef
8
+ ) {
9
+
10
+ const map = useMap()
11
+
12
+ const render = useFunction((_gl: WebGL2RenderingContext, matrix: number[])=>{
13
+ if(!map.current) return;
14
+ if(!ref.current?.state) return;
15
+ const camera = ref.current.state.camera;
16
+ const gl = ref.current.state.gl;
17
+ const advance = ref.current.state.advance;
18
+ camera.projectionMatrix.fromArray(matrix).multiply(m4);
19
+ camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
20
+ gl.resetState();
21
+ advance(Date.now() * 0.001, true);
22
+ map.current.triggerRepaint();
23
+ })
24
+
25
+ return render;
26
+
27
+ }
package/src/main.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './canvas/canvas';
@@ -0,0 +1,28 @@
1
+ import { ThemeState, useLadleContext } from "@ladle/react";
2
+ import 'maplibre-gl/dist/maplibre-gl.css';
3
+ import Map from 'react-map-gl/maplibre';
4
+ import { Canvas } from "../canvas/canvas";
5
+ import { MyScene } from "./my-scene";
6
+
7
+ export function BasicSetup() {
8
+ const theme = useLadleContext().globalState.theme;
9
+ const mapStyle = theme === ThemeState.Dark
10
+ ? "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
11
+ : "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
12
+ return <div style={{ height: '100vh' }}>
13
+ <Map
14
+ antialias
15
+ initialViewState={{
16
+ latitude: 51.5073218,
17
+ longitude: -0.1276473,
18
+ zoom: 22
19
+ }}
20
+ mapStyle={mapStyle}
21
+ >
22
+ <Canvas latitude={51.5073218} longitude={-0.1276473}>
23
+ <MyScene />
24
+ </Canvas>
25
+ </Map>
26
+ </div>
27
+ }
28
+
@@ -0,0 +1,83 @@
1
+ import { Box, Plane, useHelper } from "@react-three/drei";
2
+ import { MeshProps, useFrame } from '@react-three/fiber';
3
+ import 'maplibre-gl/dist/maplibre-gl.css';
4
+ import { useRef, useState } from 'react';
5
+ import { CameraHelper, MathUtils, Mesh, OrthographicCamera } from "three";
6
+
7
+ export function MyScene() {
8
+ return <>
9
+ <Lights />
10
+ <Floor />
11
+ <MyBox position={[-1.2, 1.5, 0]} />
12
+ <MyBox position={[1.2, 1.5, 0]} />
13
+ <MyBox position={[1.2, 1.5, 2.4]} />
14
+ </>
15
+ }
16
+
17
+
18
+ function MyBox(props: MeshProps) {
19
+ const [hovered, hover] = useState(false);
20
+ const [clicked, click] = useState(false);
21
+ const mesh = useRef<Mesh>(null)
22
+
23
+ useFrame((_st, dt)=>{
24
+ if(!mesh.current) return;
25
+ mesh.current.rotateY(dt);
26
+ })
27
+
28
+ return (
29
+ <Box
30
+ {...props}
31
+ ref={mesh}
32
+ args={[1, 1, 1]}
33
+ receiveShadow
34
+ castShadow
35
+ scale={props.scale || clicked ? props.scale || 1.5 : 1}
36
+ onClick={() => click(!clicked)}
37
+ onPointerOver={() => hover(true)}
38
+ onPointerOut={() => hover(false)}
39
+ >
40
+ <meshStandardMaterial
41
+ color={hovered ? "red" : "orange"}
42
+ metalness={.75}
43
+ roughness={.5}
44
+ />
45
+ </Box>
46
+ );
47
+ }
48
+ function Lights() {
49
+ const cam = useRef<OrthographicCamera>(null);
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ useHelper(cam as any, CameraHelper)
52
+ const camSize = 5;
53
+ return <>
54
+ <ambientLight intensity={0.5} />
55
+ <directionalLight
56
+ castShadow
57
+ position={[2.5, 50, 5]}
58
+ intensity={1.5}
59
+ shadow-mapSize={1024}
60
+ shadow-bias={-0.005}
61
+ >
62
+ <orthographicCamera
63
+ ref={cam}
64
+ attach="shadow-camera"
65
+ args={[-camSize, camSize, -camSize, camSize, 0.1, 100]}
66
+ rotation={[0,90*MathUtils.DEG2RAD,0]}
67
+ />
68
+ </directionalLight>
69
+ <pointLight position={[-10, 0, -20]} color="white" intensity={1} />
70
+ <pointLight position={[0, -10, 0]} intensity={1} />
71
+ </>
72
+ }
73
+
74
+ function Floor() {
75
+ return <Plane
76
+ args={[50, 50]}
77
+ position={[0, 0, 0]}
78
+ rotation={[-90 * MathUtils.DEG2RAD, 0, 0]}
79
+ receiveShadow
80
+ >
81
+ <shadowMaterial opacity={.5} />
82
+ </Plane>
83
+ }
@@ -0,0 +1,12 @@
1
+ import { MapControls } from "@react-three/drei"
2
+ import { Canvas } from "@react-three/fiber"
3
+ import { MyScene } from "./my-scene"
4
+
5
+ export const NoMap = () => {
6
+ return <div style={{ height: '100vh' }}>
7
+ <Canvas camera={{position: [0,10,0]}} shadows="basic">
8
+ <MyScene />
9
+ <MapControls makeDefault />
10
+ </Canvas>
11
+ </div>
12
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/tsconfig.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "jsx": "react-jsx",
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noFallthroughCasesInSwitch": true
22
+ },
23
+ "include": ["src"],
24
+ "references": [{ "path": "./tsconfig.node.json" }]
25
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true
8
+ },
9
+ "include": ["vite.config.ts"]
10
+ }