react-three-map 0.3.2 → 0.3.4
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.
- package/CHANGELOG.md +12 -0
- package/README.md +4 -4
- package/dist/cjs/web-ifc.wasm +0 -0
- package/dist/es/web-ifc.wasm +0 -0
- package/dist/maplibre/cjs/web-ifc.wasm +0 -0
- package/dist/maplibre/es/web-ifc.wasm +0 -0
- package/dist/maplibre/types/core/coords-to-matrix.d.ts +8 -0
- package/dist/maplibre/types/core/create-events.d.ts +3 -0
- package/dist/maplibre/types/core/generic-map.d.ts +47 -0
- package/{src/core/state-ref.ts → dist/maplibre/types/core/state-ref.d.ts} +4 -5
- package/dist/maplibre/types/core/use-canvas.d.ts +13 -0
- package/dist/maplibre/types/core/use-function.d.ts +1 -0
- package/dist/maplibre/types/core/use-on-add.d.ts +8 -0
- package/dist/maplibre/types/core/use-render.d.ts +3 -0
- package/dist/maplibre/types/maplibre/canvas.d.ts +10 -0
- package/dist/maplibre/types/maplibre.index.d.ts +1 -0
- package/dist/types/core/coords-to-matrix.d.ts +8 -0
- package/dist/types/core/create-events.d.ts +3 -0
- package/dist/types/core/generic-map.d.ts +47 -0
- package/dist/types/core/state-ref.d.ts +8 -0
- package/dist/types/core/use-canvas.d.ts +13 -0
- package/dist/types/core/use-function.d.ts +1 -0
- package/dist/types/core/use-on-add.d.ts +8 -0
- package/dist/types/core/use-render.d.ts +3 -0
- package/dist/types/mapbox/canvas.d.ts +10 -0
- package/dist/types/mapbox.index.d.ts +1 -0
- package/maplibre/package.json +1 -1
- package/package.json +8 -5
- package/docs/basic-app.gif +0 -0
- package/example-mapbox/package.json +0 -29
- package/example-mapbox/sandbox.config.json +0 -3
- package/example-mapbox/src/canvas.basic.stories.tsx +0 -84
- package/example-mapbox/src/comparison.stories.tsx +0 -37
- package/example-mapbox/src/html-on-top.stories.tsx +0 -24
- package/example-mapbox/src/my-scene.tsx +0 -89
- package/example-mapbox/src/render-on-demand.stories.tsx +0 -32
- package/example-mapbox/src/story-map.tsx +0 -61
- package/example-mapbox/src/vite-env.d.ts +0 -1
- package/example-mapbox/tsconfig.json +0 -27
- package/example-mapbox/tsconfig.node.json +0 -10
- package/example-mapbox/yarn.lock +0 -4154
- package/example-maplibre/package.json +0 -29
- package/example-maplibre/sandbox.config.json +0 -3
- package/example-maplibre/src/canvas.basic.stories.tsx +0 -61
- package/example-maplibre/src/comparison.stories.tsx +0 -35
- package/example-maplibre/src/html-on-top.stories.tsx +0 -24
- package/example-maplibre/src/my-scene.tsx +0 -89
- package/example-maplibre/src/render-on-demand.stories.tsx +0 -32
- package/example-maplibre/src/story-map.tsx +0 -38
- package/example-maplibre/src/vite-env.d.ts +0 -1
- package/example-maplibre/tsconfig.json +0 -25
- package/example-maplibre/tsconfig.node.json +0 -10
- package/example-maplibre/yarn.lock +0 -4181
- package/src/core/coords-to-matrix.ts +0 -20
- package/src/core/create-events.ts +0 -73
- package/src/core/generic-map.test.ts +0 -2
- package/src/core/generic-map.ts +0 -57
- package/src/core/use-canvas.tsx +0 -31
- package/src/core/use-function.ts +0 -10
- package/src/core/use-on-add.ts +0 -90
- package/src/core/use-render.ts +0 -25
- package/src/mapbox/canvas.tsx +0 -38
- package/src/mapbox/index.ts +0 -1
- package/src/maplibre/canvas.tsx +0 -38
- package/src/maplibre/index.ts +0 -1
- package/src/stories/comparison.stories.tsx +0 -38
- package/src/stories/html-on-top.stories.tsx +0 -21
- package/src/stories/mapbox/story-mapbox.tsx +0 -58
- package/src/stories/mapbox-example.stories.tsx +0 -84
- package/src/stories/maplibre/story-maplibre.tsx +0 -32
- package/src/stories/maplibre-example.stories.tsx +0 -61
- package/src/stories/my-scene.tsx +0 -88
- package/src/stories/render-on-demand.stories.tsx +0 -34
- package/src/stories/story-map.tsx +0 -35
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.json +0 -30
- package/tsconfig.node.json +0 -10
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Euler, Matrix4, Quaternion, Vector3 } from "three";
|
|
2
|
-
import { FromLngLat } from "./generic-map";
|
|
3
|
-
|
|
4
|
-
const quat = new Quaternion();
|
|
5
|
-
const euler = new Euler();
|
|
6
|
-
const pos = new Vector3();
|
|
7
|
-
const scale = new Vector3();
|
|
8
|
-
const m4 = new Matrix4();
|
|
9
|
-
|
|
10
|
-
/** calculate Matrix4 from coordinates */
|
|
11
|
-
export function coordsToMatrix({ longitude, latitude, altitude, fromLngLat }: {
|
|
12
|
-
longitude: number, latitude: number, altitude: number, fromLngLat: FromLngLat
|
|
13
|
-
}) {
|
|
14
|
-
const center = fromLngLat([longitude, latitude], altitude);
|
|
15
|
-
const scaleUnit = center.meterInMercatorCoordinateUnits();
|
|
16
|
-
pos.set(center.x, center.y, center.z || 0);
|
|
17
|
-
scale.set(scaleUnit, -scaleUnit, scaleUnit);
|
|
18
|
-
quat.setFromEuler(euler.set(-Math.PI * .5, 0, 0));
|
|
19
|
-
return m4.compose(pos, quat, scale).toArray();
|
|
20
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
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 / window.devicePixelRatio;
|
|
28
|
-
state.size.height = state.gl.domElement.height / window.devicePixelRatio;
|
|
29
|
-
state.pointer.x = (event.offsetX / state.size.width) * 2 - 1;
|
|
30
|
-
state.pointer.y = 1 - (event.offsetY / state.size.height) * 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.parentNode } }));
|
|
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
|
-
}
|
package/src/core/generic-map.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// mock of functions used by `react-three-map` from `Maplibre` or `Mapbox`
|
|
2
|
-
|
|
3
|
-
/** Generic interface of Mapbox/Maplibre `LayerProps` */
|
|
4
|
-
export interface LayerProps {
|
|
5
|
-
id: string;
|
|
6
|
-
type: 'custom';
|
|
7
|
-
renderingMode: '3d';
|
|
8
|
-
onRemove?(map: MapInstance, gl: WebGLRenderingContext): void;
|
|
9
|
-
onAdd?(map: MapInstance, gl: WebGLRenderingContext): void;
|
|
10
|
-
prerender?(gl: WebGLRenderingContext, matrix: number[]): void;
|
|
11
|
-
render(gl: WebGLRenderingContext, matrix: number[]): void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** Generic interface of Mapbox/Maplibre `LngLatLike` */
|
|
15
|
-
export type LngLatLike = {
|
|
16
|
-
lng: number;
|
|
17
|
-
lat: number;
|
|
18
|
-
} | {
|
|
19
|
-
lon: number;
|
|
20
|
-
lat: number;
|
|
21
|
-
} | [
|
|
22
|
-
number,
|
|
23
|
-
number
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
/** Generic interface of Mapbox/Maplibre `static MercatorCoordinate.fromLngLat` */
|
|
27
|
-
export type FromLngLat = (lngLatLike: LngLatLike, altitude?: number) => MercatorCoordinate;
|
|
28
|
-
|
|
29
|
-
/** Generic interface of Mapbox/Maplibre typeof `MercatorCoordinate` */
|
|
30
|
-
export interface MercatorCoordinate {
|
|
31
|
-
x: number;
|
|
32
|
-
y: number;
|
|
33
|
-
z?: number;
|
|
34
|
-
meterInMercatorCoordinateUnits(): number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Generic interface of Mapbox/Maplibre `Map` */
|
|
38
|
-
export interface MapInstance {
|
|
39
|
-
getCanvas(): HTMLCanvasElement;
|
|
40
|
-
triggerRepaint(): void;
|
|
41
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
42
|
-
on<T extends keyof MapEventType>(type: T, listener: (ev: MapEventType[T] & Object) => void): this;
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
44
|
-
off<T extends keyof MapEventType>(type: T, listener: (ev: MapEventType[T] & Object) => void): this;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/** Generic interface of Mapbox/Maplibre `MapEventType` */
|
|
48
|
-
export type MapEventType = {
|
|
49
|
-
resize: MapEvent;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/** Generic interface of `MapLibreEvent` or `MapBoxEvent` */
|
|
53
|
-
export interface MapEvent<TOrig = unknown> {
|
|
54
|
-
type: string;
|
|
55
|
-
target: MapInstance;
|
|
56
|
-
originalEvent: TOrig;
|
|
57
|
-
}
|
package/src/core/use-canvas.tsx
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { RenderProps } from "@react-three/fiber";
|
|
2
|
-
import { PropsWithChildren, useEffect, useId, useRef } from "react";
|
|
3
|
-
import { Matrix4Tuple } from "three";
|
|
4
|
-
import { StateRef } from "./state-ref";
|
|
5
|
-
import { useOnAdd } from "./use-on-add";
|
|
6
|
-
import { useRender } from "./use-render";
|
|
7
|
-
|
|
8
|
-
export interface useCanvasProps extends Omit<RenderProps<HTMLCanvasElement>, 'frameloop'>, PropsWithChildren {
|
|
9
|
-
frameloop: 'always' | 'demand',
|
|
10
|
-
m4: Matrix4Tuple;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const useCanvas = (({
|
|
14
|
-
m4, children, frameloop, ...renderProps
|
|
15
|
-
}: useCanvasProps) => {
|
|
16
|
-
const id = useId();
|
|
17
|
-
|
|
18
|
-
const stateRef: StateRef = useRef();
|
|
19
|
-
|
|
20
|
-
const { onAdd, onRemove, mounted } = useOnAdd(stateRef, { frameloop, ...renderProps });
|
|
21
|
-
|
|
22
|
-
const render = useRender(m4, stateRef, frameloop);
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
if (!mounted) return;
|
|
26
|
-
if (!stateRef.current) return;
|
|
27
|
-
stateRef.current.root.render(<>{children}</>);
|
|
28
|
-
}, [stateRef, mounted, children])
|
|
29
|
-
|
|
30
|
-
return { id, onAdd, onRemove, render }
|
|
31
|
-
})
|
package/src/core/use-function.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
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
|
-
};
|
package/src/core/use-on-add.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { RenderProps, createRoot } from "@react-three/fiber";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import { createEvents } from "./create-events";
|
|
4
|
-
import { MapInstance } from "./generic-map";
|
|
5
|
-
import { StateRef } from "./state-ref";
|
|
6
|
-
import { useFunction } from "./use-function";
|
|
7
|
-
|
|
8
|
-
export function useOnAdd(ref: StateRef, { frameloop, ...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
|
-
dpr: window.devicePixelRatio,
|
|
18
|
-
events: createEvents(),
|
|
19
|
-
...renderProps,
|
|
20
|
-
frameloop: 'never',
|
|
21
|
-
gl: {
|
|
22
|
-
context: gl,
|
|
23
|
-
depth: true,
|
|
24
|
-
autoClear: false,
|
|
25
|
-
antialias: true,
|
|
26
|
-
...renderProps?.gl,
|
|
27
|
-
},
|
|
28
|
-
onCreated: (state) => {
|
|
29
|
-
|
|
30
|
-
if (frameloop === 'demand') {
|
|
31
|
-
state.set({
|
|
32
|
-
frameloop,
|
|
33
|
-
invalidate: () => {
|
|
34
|
-
map.triggerRepaint();
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
ref.current = {
|
|
40
|
-
state,
|
|
41
|
-
map,
|
|
42
|
-
root,
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
46
|
-
state.gl.forceContextLoss = () => { };
|
|
47
|
-
|
|
48
|
-
// we update the camera on create rather than on config
|
|
49
|
-
// because otherwise some components may use it too early
|
|
50
|
-
// and get NaN values they can't recover from (drei HTML)
|
|
51
|
-
state.camera.matrixAutoUpdate = false;
|
|
52
|
-
},
|
|
53
|
-
size: {
|
|
54
|
-
width: canvas.clientWidth,
|
|
55
|
-
height: canvas.clientHeight,
|
|
56
|
-
top: 0,
|
|
57
|
-
left: 0,
|
|
58
|
-
...renderProps?.size,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
ref.current = {
|
|
63
|
-
map,
|
|
64
|
-
root,
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
map.on('resize', onResize)
|
|
68
|
-
|
|
69
|
-
setTimeout(() => setMounted(true));
|
|
70
|
-
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
const onResize = useFunction(() => {
|
|
74
|
-
if (!ref.current?.state) return;
|
|
75
|
-
const state = ref.current.state;
|
|
76
|
-
const map = ref.current.map;
|
|
77
|
-
const canvas = map.getCanvas();
|
|
78
|
-
state.setSize(canvas.width, canvas.height);
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const onRemove = useFunction((map: MapInstance) => {
|
|
82
|
-
setTimeout(() => {
|
|
83
|
-
if (!ref.current) return;
|
|
84
|
-
ref.current.root.unmount();
|
|
85
|
-
map.off('resize', onResize)
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
return { onAdd, onRemove, mounted };
|
|
90
|
-
}
|
package/src/core/use-render.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Matrix4, Matrix4Tuple } from "three";
|
|
2
|
-
import { StateRef } from "./state-ref";
|
|
3
|
-
import { useFunction } from "./use-function";
|
|
4
|
-
|
|
5
|
-
const mx = new Matrix4();
|
|
6
|
-
|
|
7
|
-
export function useRender(
|
|
8
|
-
m4: Matrix4Tuple, stateRef: StateRef, frameloop: 'always' | 'demand'
|
|
9
|
-
) {
|
|
10
|
-
|
|
11
|
-
const render = useFunction((_gl: WebGL2RenderingContext, matrix: number[]) => {
|
|
12
|
-
if (!stateRef.current?.state) return;
|
|
13
|
-
const camera = stateRef.current.state.camera;
|
|
14
|
-
const gl = stateRef.current.state.gl;
|
|
15
|
-
const advance = stateRef.current.state.advance;
|
|
16
|
-
camera.projectionMatrix.fromArray(matrix).multiply(mx.fromArray(m4));
|
|
17
|
-
camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
|
|
18
|
-
gl.resetState();
|
|
19
|
-
advance(Date.now() * 0.001, true);
|
|
20
|
-
if (frameloop === 'always') stateRef.current.map.triggerRepaint();
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
return render;
|
|
24
|
-
|
|
25
|
-
}
|
package/src/mapbox/canvas.tsx
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { RenderProps, extend } from "@react-three/fiber";
|
|
2
|
-
import { MercatorCoordinate } from "mapbox-gl";
|
|
3
|
-
import { PropsWithChildren, memo, useMemo } from "react";
|
|
4
|
-
import { Layer } from "react-map-gl";
|
|
5
|
-
import * as THREE from "three";
|
|
6
|
-
import { coordsToMatrix } from "../core/coords-to-matrix";
|
|
7
|
-
import { useCanvas } from "../core/use-canvas";
|
|
8
|
-
|
|
9
|
-
extend(THREE);
|
|
10
|
-
|
|
11
|
-
export interface CanvasProps extends Omit<RenderProps<HTMLCanvasElement>, 'frameloop'>, PropsWithChildren {
|
|
12
|
-
longitude: number,
|
|
13
|
-
latitude: number,
|
|
14
|
-
altitude?: number,
|
|
15
|
-
frameloop?: 'always' | 'demand',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** react`-three-fiber` canvas inside `MapLibre` */
|
|
19
|
-
export const Canvas = memo<CanvasProps>(({
|
|
20
|
-
longitude, latitude, altitude = 0,
|
|
21
|
-
frameloop = 'always', ...renderProps
|
|
22
|
-
}) => {
|
|
23
|
-
|
|
24
|
-
const m4 = useMemo(() => coordsToMatrix({
|
|
25
|
-
latitude, longitude, altitude, fromLngLat: MercatorCoordinate.fromLngLat,
|
|
26
|
-
}), [latitude, longitude, altitude]);
|
|
27
|
-
|
|
28
|
-
const { id, onAdd, onRemove, render } = useCanvas({ m4, frameloop, ...renderProps });
|
|
29
|
-
|
|
30
|
-
return <Layer
|
|
31
|
-
id={id}
|
|
32
|
-
type="custom"
|
|
33
|
-
renderingMode="3d"
|
|
34
|
-
onAdd={onAdd}
|
|
35
|
-
onRemove={onRemove}
|
|
36
|
-
render={render}
|
|
37
|
-
/>
|
|
38
|
-
})
|
package/src/mapbox/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './canvas';
|
package/src/maplibre/canvas.tsx
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { RenderProps, extend } from "@react-three/fiber";
|
|
2
|
-
import { MercatorCoordinate } from "maplibre-gl";
|
|
3
|
-
import { PropsWithChildren, memo, useMemo } from "react";
|
|
4
|
-
import { Layer } from "react-map-gl/maplibre";
|
|
5
|
-
import * as THREE from "three";
|
|
6
|
-
import { coordsToMatrix } from "../core/coords-to-matrix";
|
|
7
|
-
import { useCanvas } from "../core/use-canvas";
|
|
8
|
-
|
|
9
|
-
extend(THREE);
|
|
10
|
-
|
|
11
|
-
export interface CanvasProps extends Omit<RenderProps<HTMLCanvasElement>, 'frameloop'>, PropsWithChildren {
|
|
12
|
-
longitude: number,
|
|
13
|
-
latitude: number,
|
|
14
|
-
altitude?: number,
|
|
15
|
-
frameloop?: 'always' | 'demand',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** react`-three-fiber` canvas inside `MapLibre` */
|
|
19
|
-
export const Canvas = memo<CanvasProps>(({
|
|
20
|
-
longitude, latitude, altitude = 0,
|
|
21
|
-
frameloop = 'always', ...renderProps
|
|
22
|
-
}) => {
|
|
23
|
-
|
|
24
|
-
const m4 = useMemo(() => coordsToMatrix({
|
|
25
|
-
latitude, longitude, altitude, fromLngLat: MercatorCoordinate.fromLngLat,
|
|
26
|
-
}), [latitude, longitude, altitude]);
|
|
27
|
-
|
|
28
|
-
const { id, onAdd, onRemove, render } = useCanvas({ m4, frameloop, ...renderProps });
|
|
29
|
-
|
|
30
|
-
return <Layer
|
|
31
|
-
id={id}
|
|
32
|
-
type="custom"
|
|
33
|
-
renderingMode="3d"
|
|
34
|
-
onAdd={onAdd}
|
|
35
|
-
onRemove={onRemove}
|
|
36
|
-
render={render}
|
|
37
|
-
/>
|
|
38
|
-
})
|
package/src/maplibre/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './canvas';
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { MapControls } from "@react-three/drei";
|
|
2
|
-
import { Canvas as FiberCanvas } from "@react-three/fiber";
|
|
3
|
-
import { useControls } from "leva";
|
|
4
|
-
import { MyScene } from "./my-scene";
|
|
5
|
-
import { StoryMap } from "./story-map";
|
|
6
|
-
|
|
7
|
-
export function WithMap() {
|
|
8
|
-
const showCamHelper = useShowCamHelper()
|
|
9
|
-
return <StoryMap
|
|
10
|
-
latitude={51.5073218}
|
|
11
|
-
longitude={-0.1276473}
|
|
12
|
-
zoom={18}
|
|
13
|
-
pitch={60}
|
|
14
|
-
canvas={{ shadows: 'variance' }}
|
|
15
|
-
>
|
|
16
|
-
<MyScene showCamHelper={showCamHelper} />
|
|
17
|
-
</StoryMap>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const WithoutMap = () => {
|
|
21
|
-
const showCamHelper = useShowCamHelper()
|
|
22
|
-
return <div style={{ height: '100vh' }}>
|
|
23
|
-
<FiberCanvas camera={{ position: [100, 100, 100] }} shadows="variance">
|
|
24
|
-
<MyScene showCamHelper={showCamHelper} />
|
|
25
|
-
<MapControls makeDefault />
|
|
26
|
-
</FiberCanvas>
|
|
27
|
-
</div>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const useShowCamHelper = () => {
|
|
31
|
-
const { showCamHelper } = useControls({
|
|
32
|
-
showCamHelper: {
|
|
33
|
-
value: false,
|
|
34
|
-
label: 'show camera helper'
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return showCamHelper
|
|
38
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Box, Html } from "@react-three/drei";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import { MathUtils } from "three";
|
|
4
|
-
import { StoryMap } from "./story-map";
|
|
5
|
-
|
|
6
|
-
export function Default() {
|
|
7
|
-
|
|
8
|
-
const [hovered, hover] = useState(false);
|
|
9
|
-
|
|
10
|
-
return <StoryMap latitude={51} longitude={0} zoom={13} pitch={60}>
|
|
11
|
-
<Html center position={[0, 250, 0]} style={{ textAlign: 'center', fontSize: '2em', width: '10em', lineHeight: '1.5em' }}><i>Some</i> <b>HTML</b><br />content!</Html>
|
|
12
|
-
<Box
|
|
13
|
-
args={[500, 500, 500]}
|
|
14
|
-
position={[0, 250, 0]}
|
|
15
|
-
rotation={[0, 45 * MathUtils.DEG2RAD, 0]}
|
|
16
|
-
onPointerOver={() => hover(true)}
|
|
17
|
-
onPointerOut={() => hover(false)}
|
|
18
|
-
material-color={hovered ? 'purple' : 'orange'}
|
|
19
|
-
/>
|
|
20
|
-
</StoryMap>
|
|
21
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { ThemeState, useLadleContext } from '@ladle/react';
|
|
2
|
-
import { useControls } from 'leva';
|
|
3
|
-
import Mapbox from "mapbox-gl";
|
|
4
|
-
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
5
|
-
import { FC, PropsWithChildren } from "react";
|
|
6
|
-
import Map from 'react-map-gl';
|
|
7
|
-
import { Canvas } from 'react-three-map';
|
|
8
|
-
import { StoryMapProps } from '../story-map';
|
|
9
|
-
|
|
10
|
-
/** `<Map>` styled for stories */
|
|
11
|
-
export const StoryMapbox: FC<StoryMapProps> = ({
|
|
12
|
-
latitude, longitude, zoom = 18, pitch = 60, canvas, children
|
|
13
|
-
}) => {
|
|
14
|
-
|
|
15
|
-
const { mapboxToken } = useControls({
|
|
16
|
-
mapboxToken: {
|
|
17
|
-
value: import.meta.env.VITE_MAPBOX_TOKEN || '',
|
|
18
|
-
label: 'mapbox token',
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const theme = useLadleContext().globalState.theme;
|
|
23
|
-
|
|
24
|
-
const mapStyle = theme === ThemeState.Dark
|
|
25
|
-
? "mapbox://styles/mapbox/dark-v11"
|
|
26
|
-
: "mapbox://styles/mapbox/streets-v12";
|
|
27
|
-
|
|
28
|
-
Mapbox.accessToken = mapboxToken;
|
|
29
|
-
|
|
30
|
-
return <div style={{ height: '100vh', position: 'relative' }}>
|
|
31
|
-
{!mapboxToken && <Center>Add a mapbox token to load this component</Center>}
|
|
32
|
-
{!!mapboxToken && <Map
|
|
33
|
-
antialias
|
|
34
|
-
initialViewState={{
|
|
35
|
-
latitude,
|
|
36
|
-
longitude,
|
|
37
|
-
zoom,
|
|
38
|
-
pitch,
|
|
39
|
-
}}
|
|
40
|
-
mapStyle={mapStyle}
|
|
41
|
-
mapboxAccessToken={mapboxToken}
|
|
42
|
-
>
|
|
43
|
-
<Canvas latitude={latitude} longitude={longitude} {...canvas}>
|
|
44
|
-
{children}
|
|
45
|
-
</Canvas>
|
|
46
|
-
</Map>}
|
|
47
|
-
</div>
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const Center = ({ children }: PropsWithChildren) => (
|
|
51
|
-
<div style={{
|
|
52
|
-
display: 'flex',
|
|
53
|
-
height: '100%',
|
|
54
|
-
width: '100%',
|
|
55
|
-
alignItems: 'center',
|
|
56
|
-
justifyContent: 'center',
|
|
57
|
-
}}>{children}</div>
|
|
58
|
-
)
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { useFrame, Vector3 } from "@react-three/fiber";
|
|
2
|
-
import { useControls } from "leva";
|
|
3
|
-
import Mapbox from "mapbox-gl";
|
|
4
|
-
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
5
|
-
import { FC, PropsWithChildren, useRef, useState } from "react";
|
|
6
|
-
import Map from 'react-map-gl';
|
|
7
|
-
import { Canvas } from "react-three-map";
|
|
8
|
-
import { Mesh } from "three";
|
|
9
|
-
|
|
10
|
-
export default { title: 'Canvas' }
|
|
11
|
-
|
|
12
|
-
export function MapboxExample() {
|
|
13
|
-
|
|
14
|
-
const { mapboxToken } = useControls({
|
|
15
|
-
mapboxToken: {
|
|
16
|
-
value: import.meta.env.VITE_MAPBOX_TOKEN || '',
|
|
17
|
-
label: 'mapbox token',
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
Mapbox.accessToken = mapboxToken;
|
|
22
|
-
|
|
23
|
-
return <div style={{ height: '100vh' }}>
|
|
24
|
-
{!mapboxToken && <Center>Add a mapbox token to load this component</Center>}
|
|
25
|
-
{!!mapboxToken && <Map
|
|
26
|
-
antialias
|
|
27
|
-
initialViewState={{
|
|
28
|
-
latitude: 51,
|
|
29
|
-
longitude: 0,
|
|
30
|
-
zoom: 13,
|
|
31
|
-
pitch: 60,
|
|
32
|
-
}}
|
|
33
|
-
mapStyle="mapbox://styles/mapbox/streets-v12"
|
|
34
|
-
>
|
|
35
|
-
<Canvas latitude={51} longitude={0}>
|
|
36
|
-
<hemisphereLight
|
|
37
|
-
args={["#ffffff", "#60666C"]}
|
|
38
|
-
position={[1, 4.5, 3]}
|
|
39
|
-
/>
|
|
40
|
-
<object3D scale={500}>
|
|
41
|
-
<Box position={[-1.2, 1, 0]} />
|
|
42
|
-
<Box position={[1.2, 1, 0]} />
|
|
43
|
-
</object3D>
|
|
44
|
-
</Canvas>
|
|
45
|
-
</Map>}
|
|
46
|
-
</div>
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const Center = ({ children }: PropsWithChildren) => (
|
|
50
|
-
<div style={{
|
|
51
|
-
display: 'flex',
|
|
52
|
-
height: '100%',
|
|
53
|
-
width: '100%',
|
|
54
|
-
alignItems: 'center',
|
|
55
|
-
justifyContent: 'center',
|
|
56
|
-
}}>{children}</div>
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
const Box: FC<{ position: Vector3 }> = (props) => {
|
|
60
|
-
// This reference gives us direct access to the THREE.Mesh object
|
|
61
|
-
const ref = useRef<Mesh>(null)
|
|
62
|
-
// Hold state for hovered and clicked events
|
|
63
|
-
const [hovered, hover] = useState(false)
|
|
64
|
-
const [clicked, click] = useState(false)
|
|
65
|
-
// Subscribe this component to the render-loop, rotate the mesh every frame
|
|
66
|
-
useFrame((_state, delta) => {
|
|
67
|
-
if (!ref.current) return;
|
|
68
|
-
ref.current.rotation.x += delta;
|
|
69
|
-
ref.current.rotation.z -= delta;
|
|
70
|
-
})
|
|
71
|
-
// Return the view, these are regular Threejs elements expressed in JSX
|
|
72
|
-
return (
|
|
73
|
-
<mesh
|
|
74
|
-
{...props}
|
|
75
|
-
ref={ref}
|
|
76
|
-
scale={clicked ? 1.5 : 1}
|
|
77
|
-
onClick={() => click(!clicked)}
|
|
78
|
-
onPointerOver={() => hover(true)}
|
|
79
|
-
onPointerOut={() => hover(false)}>
|
|
80
|
-
<boxGeometry args={[1, 1, 1]} />
|
|
81
|
-
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
|
|
82
|
-
</mesh>
|
|
83
|
-
)
|
|
84
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ThemeState, useLadleContext } from '@ladle/react';
|
|
2
|
-
import MapLibre from "maplibre-gl";
|
|
3
|
-
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
4
|
-
import { FC } from "react";
|
|
5
|
-
import Map from 'react-map-gl/maplibre';
|
|
6
|
-
import { StoryMapProps } from '../story-map';
|
|
7
|
-
import { Canvas } from 'react-three-map/maplibre';
|
|
8
|
-
|
|
9
|
-
/** Maplibre `<Map>` styled for stories */
|
|
10
|
-
export const StoryMaplibre: FC<StoryMapProps> = ({
|
|
11
|
-
latitude, longitude, zoom, pitch, canvas, children
|
|
12
|
-
}) => {
|
|
13
|
-
|
|
14
|
-
const theme = useLadleContext().globalState.theme;
|
|
15
|
-
|
|
16
|
-
const mapStyle = theme === ThemeState.Dark
|
|
17
|
-
? "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
|
|
18
|
-
: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json";
|
|
19
|
-
|
|
20
|
-
return <div style={{ height: '100vh', position: 'relative' }}>
|
|
21
|
-
<Map
|
|
22
|
-
mapLib={MapLibre}
|
|
23
|
-
antialias
|
|
24
|
-
initialViewState={{ latitude, longitude, zoom, pitch, }}
|
|
25
|
-
mapStyle={mapStyle}
|
|
26
|
-
>
|
|
27
|
-
<Canvas latitude={latitude} longitude={longitude} {...canvas}>
|
|
28
|
-
{children}
|
|
29
|
-
</Canvas>
|
|
30
|
-
</Map>
|
|
31
|
-
</div>
|
|
32
|
-
}
|