react-three-map 0.3.2 → 0.3.3

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 (72) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/maplibre/types/core/coords-to-matrix.d.ts +8 -0
  3. package/dist/maplibre/types/core/create-events.d.ts +3 -0
  4. package/dist/maplibre/types/core/generic-map.d.ts +47 -0
  5. package/{src/core/state-ref.ts → dist/maplibre/types/core/state-ref.d.ts} +4 -5
  6. package/dist/maplibre/types/core/use-canvas.d.ts +13 -0
  7. package/dist/maplibre/types/core/use-function.d.ts +1 -0
  8. package/dist/maplibre/types/core/use-on-add.d.ts +8 -0
  9. package/dist/maplibre/types/core/use-render.d.ts +3 -0
  10. package/dist/maplibre/types/maplibre/canvas.d.ts +10 -0
  11. package/dist/maplibre/types/maplibre.index.d.ts +1 -0
  12. package/dist/types/core/coords-to-matrix.d.ts +8 -0
  13. package/dist/types/core/create-events.d.ts +3 -0
  14. package/dist/types/core/generic-map.d.ts +47 -0
  15. package/dist/types/core/state-ref.d.ts +8 -0
  16. package/dist/types/core/use-canvas.d.ts +13 -0
  17. package/dist/types/core/use-function.d.ts +1 -0
  18. package/dist/types/core/use-on-add.d.ts +8 -0
  19. package/dist/types/core/use-render.d.ts +3 -0
  20. package/dist/types/mapbox/canvas.d.ts +10 -0
  21. package/dist/types/mapbox.index.d.ts +1 -0
  22. package/maplibre/package.json +1 -1
  23. package/package.json +4 -3
  24. package/docs/basic-app.gif +0 -0
  25. package/example-mapbox/package.json +0 -29
  26. package/example-mapbox/sandbox.config.json +0 -3
  27. package/example-mapbox/src/canvas.basic.stories.tsx +0 -84
  28. package/example-mapbox/src/comparison.stories.tsx +0 -37
  29. package/example-mapbox/src/html-on-top.stories.tsx +0 -24
  30. package/example-mapbox/src/my-scene.tsx +0 -89
  31. package/example-mapbox/src/render-on-demand.stories.tsx +0 -32
  32. package/example-mapbox/src/story-map.tsx +0 -61
  33. package/example-mapbox/src/vite-env.d.ts +0 -1
  34. package/example-mapbox/tsconfig.json +0 -27
  35. package/example-mapbox/tsconfig.node.json +0 -10
  36. package/example-mapbox/yarn.lock +0 -4154
  37. package/example-maplibre/package.json +0 -29
  38. package/example-maplibre/sandbox.config.json +0 -3
  39. package/example-maplibre/src/canvas.basic.stories.tsx +0 -61
  40. package/example-maplibre/src/comparison.stories.tsx +0 -35
  41. package/example-maplibre/src/html-on-top.stories.tsx +0 -24
  42. package/example-maplibre/src/my-scene.tsx +0 -89
  43. package/example-maplibre/src/render-on-demand.stories.tsx +0 -32
  44. package/example-maplibre/src/story-map.tsx +0 -38
  45. package/example-maplibre/src/vite-env.d.ts +0 -1
  46. package/example-maplibre/tsconfig.json +0 -25
  47. package/example-maplibre/tsconfig.node.json +0 -10
  48. package/example-maplibre/yarn.lock +0 -4181
  49. package/src/core/coords-to-matrix.ts +0 -20
  50. package/src/core/create-events.ts +0 -73
  51. package/src/core/generic-map.test.ts +0 -2
  52. package/src/core/generic-map.ts +0 -57
  53. package/src/core/use-canvas.tsx +0 -31
  54. package/src/core/use-function.ts +0 -10
  55. package/src/core/use-on-add.ts +0 -90
  56. package/src/core/use-render.ts +0 -25
  57. package/src/mapbox/canvas.tsx +0 -38
  58. package/src/mapbox/index.ts +0 -1
  59. package/src/maplibre/canvas.tsx +0 -38
  60. package/src/maplibre/index.ts +0 -1
  61. package/src/stories/comparison.stories.tsx +0 -38
  62. package/src/stories/html-on-top.stories.tsx +0 -21
  63. package/src/stories/mapbox/story-mapbox.tsx +0 -58
  64. package/src/stories/mapbox-example.stories.tsx +0 -84
  65. package/src/stories/maplibre/story-maplibre.tsx +0 -32
  66. package/src/stories/maplibre-example.stories.tsx +0 -61
  67. package/src/stories/my-scene.tsx +0 -88
  68. package/src/stories/render-on-demand.stories.tsx +0 -34
  69. package/src/stories/story-map.tsx +0 -35
  70. package/src/vite-env.d.ts +0 -1
  71. package/tsconfig.json +0 -30
  72. 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
- }
@@ -1,2 +0,0 @@
1
- // add type tests to make sure our generic functions
2
- // can be satisfied by Mapbox and Maplibre
@@ -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
- }
@@ -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
- })
@@ -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
- };
@@ -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
- }
@@ -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
- }
@@ -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
- })
@@ -1 +0,0 @@
1
- export * from './canvas';
@@ -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
- })
@@ -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
- }