react-three-map 0.7.2 → 0.8.0

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 (138) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +42 -4
  3. package/dist/cjs/main.js +369 -181
  4. package/dist/es/main.mjs +6 -2
  5. package/dist/es/main.mjs.map +1 -1
  6. package/dist/es/main10.mjs +33 -20
  7. package/dist/es/main10.mjs.map +1 -1
  8. package/dist/es/main11.mjs +11 -19
  9. package/dist/es/main11.mjs.map +1 -1
  10. package/dist/es/main12.mjs +20 -85
  11. package/dist/es/main12.mjs.map +1 -1
  12. package/dist/es/main13.mjs +30 -9
  13. package/dist/es/main13.mjs.map +1 -1
  14. package/dist/es/main14.mjs +22 -67
  15. package/dist/es/main14.mjs.map +1 -1
  16. package/dist/es/main15.mjs +98 -0
  17. package/dist/es/main15.mjs.map +1 -0
  18. package/dist/es/main16.mjs +66 -0
  19. package/dist/es/main16.mjs.map +1 -0
  20. package/dist/es/main17.mjs +23 -0
  21. package/dist/es/main17.mjs.map +1 -0
  22. package/dist/es/main18.mjs +27 -0
  23. package/dist/es/main18.mjs.map +1 -0
  24. package/dist/es/main19.mjs +19 -0
  25. package/dist/es/main19.mjs.map +1 -0
  26. package/dist/es/main2.mjs.map +1 -1
  27. package/dist/es/main20.mjs +72 -0
  28. package/dist/es/main20.mjs.map +1 -0
  29. package/dist/es/main3.mjs +43 -50
  30. package/dist/es/main3.mjs.map +1 -1
  31. package/dist/es/main4.mjs +50 -24
  32. package/dist/es/main4.mjs.map +1 -1
  33. package/dist/es/main5.mjs +19 -3
  34. package/dist/es/main5.mjs.map +1 -1
  35. package/dist/es/main6.mjs +14 -33
  36. package/dist/es/main6.mjs.map +1 -1
  37. package/dist/es/main7.mjs +18 -7
  38. package/dist/es/main7.mjs.map +1 -1
  39. package/dist/es/main8.mjs +26 -21
  40. package/dist/es/main8.mjs.map +1 -1
  41. package/dist/es/main9.mjs +9 -15
  42. package/dist/es/main9.mjs.map +1 -1
  43. package/dist/maplibre/cjs/main.js +369 -181
  44. package/dist/maplibre/es/main.mjs +6 -2
  45. package/dist/maplibre/es/main.mjs.map +1 -1
  46. package/dist/maplibre/es/main10.mjs +33 -19
  47. package/dist/maplibre/es/main10.mjs.map +1 -1
  48. package/dist/maplibre/es/main11.mjs +11 -14
  49. package/dist/maplibre/es/main11.mjs.map +1 -1
  50. package/dist/maplibre/es/main12.mjs +20 -85
  51. package/dist/maplibre/es/main12.mjs.map +1 -1
  52. package/dist/maplibre/es/main13.mjs +30 -9
  53. package/dist/maplibre/es/main13.mjs.map +1 -1
  54. package/dist/maplibre/es/main14.mjs +22 -67
  55. package/dist/maplibre/es/main14.mjs.map +1 -1
  56. package/dist/maplibre/es/main15.mjs +98 -0
  57. package/dist/maplibre/es/main15.mjs.map +1 -0
  58. package/dist/maplibre/es/main16.mjs +66 -0
  59. package/dist/maplibre/es/main16.mjs.map +1 -0
  60. package/dist/maplibre/es/main17.mjs +23 -0
  61. package/dist/maplibre/es/main17.mjs.map +1 -0
  62. package/dist/maplibre/es/main18.mjs +27 -0
  63. package/dist/maplibre/es/main18.mjs.map +1 -0
  64. package/dist/maplibre/es/main19.mjs +19 -0
  65. package/dist/maplibre/es/main19.mjs.map +1 -0
  66. package/dist/maplibre/es/main2.mjs.map +1 -1
  67. package/dist/maplibre/es/main20.mjs +72 -0
  68. package/dist/maplibre/es/main20.mjs.map +1 -0
  69. package/dist/maplibre/es/main3.mjs +43 -50
  70. package/dist/maplibre/es/main3.mjs.map +1 -1
  71. package/dist/maplibre/es/main4.mjs +50 -24
  72. package/dist/maplibre/es/main4.mjs.map +1 -1
  73. package/dist/maplibre/es/main5.mjs +19 -3
  74. package/dist/maplibre/es/main5.mjs.map +1 -1
  75. package/dist/maplibre/es/main6.mjs +14 -33
  76. package/dist/maplibre/es/main6.mjs.map +1 -1
  77. package/dist/maplibre/es/main7.mjs +18 -7
  78. package/dist/maplibre/es/main7.mjs.map +1 -1
  79. package/dist/maplibre/es/main8.mjs +26 -21
  80. package/dist/maplibre/es/main8.mjs.map +1 -1
  81. package/dist/maplibre/es/main9.mjs +8 -20
  82. package/dist/maplibre/es/main9.mjs.map +1 -1
  83. package/dist/maplibre/types/api/canvas-props.d.ts +4 -4
  84. package/dist/maplibre/types/api/coords-to-vector-3.d.ts +4 -0
  85. package/dist/maplibre/types/api/coords.d.ts +5 -0
  86. package/dist/maplibre/types/api/index.d.ts +5 -0
  87. package/dist/maplibre/types/api/near-coordinates.d.ts +3 -0
  88. package/dist/maplibre/types/api/use-map.d.ts +1 -1
  89. package/dist/maplibre/types/core/canvas-in-layer/use-canvas-in-layer.d.ts +11 -0
  90. package/dist/maplibre/types/core/canvas-in-layer/use-render.d.ts +12 -0
  91. package/dist/maplibre/types/core/canvas-in-layer/use-root.d.ts +7 -0
  92. package/dist/maplibre/types/core/canvas-overlay/canvas-portal.d.ts +11 -0
  93. package/dist/maplibre/types/core/canvas-overlay/init-canvas-fc.d.ts +12 -0
  94. package/dist/maplibre/types/core/canvas-overlay/init-r3m.d.ts +10 -0
  95. package/dist/maplibre/types/core/canvas-overlay/render.d.ts +1 -0
  96. package/dist/maplibre/types/core/canvas-overlay/sync-camera-fc.d.ts +13 -0
  97. package/dist/maplibre/types/core/coords-to-matrix.d.ts +2 -4
  98. package/dist/maplibre/types/core/events.d.ts +4 -0
  99. package/dist/maplibre/types/core/use-coords-to-matrix.d.ts +5 -0
  100. package/dist/maplibre/types/core/use-coords.d.ts +7 -5
  101. package/dist/maplibre/types/core/use-r3m.d.ts +22 -0
  102. package/dist/maplibre/types/{maplibre → mapbox}/canvas.d.ts +1 -1
  103. package/dist/maplibre/types/maplibre.index.d.ts +3 -4
  104. package/dist/types/api/canvas-props.d.ts +4 -4
  105. package/dist/types/api/coords-to-vector-3.d.ts +4 -0
  106. package/dist/types/api/coords.d.ts +5 -0
  107. package/dist/types/api/index.d.ts +5 -0
  108. package/dist/types/api/near-coordinates.d.ts +3 -0
  109. package/dist/types/api/use-map.d.ts +1 -1
  110. package/dist/types/core/canvas-in-layer/use-canvas-in-layer.d.ts +11 -0
  111. package/dist/types/core/canvas-in-layer/use-render.d.ts +12 -0
  112. package/dist/types/core/canvas-in-layer/use-root.d.ts +7 -0
  113. package/dist/types/core/canvas-overlay/canvas-portal.d.ts +11 -0
  114. package/dist/types/core/canvas-overlay/init-canvas-fc.d.ts +12 -0
  115. package/dist/types/core/canvas-overlay/init-r3m.d.ts +10 -0
  116. package/dist/types/core/canvas-overlay/render.d.ts +1 -0
  117. package/dist/types/core/canvas-overlay/sync-camera-fc.d.ts +13 -0
  118. package/dist/types/core/coords-to-matrix.d.ts +2 -4
  119. package/dist/types/core/events.d.ts +4 -0
  120. package/dist/types/core/use-coords-to-matrix.d.ts +5 -0
  121. package/dist/types/core/use-coords.d.ts +7 -5
  122. package/dist/types/core/use-r3m.d.ts +22 -0
  123. package/dist/types/mapbox.index.d.ts +2 -3
  124. package/package.json +12 -9
  125. package/stories/package.json +12 -5
  126. package/stories/yarn.lock +128 -135
  127. package/dist/maplibre/types/core/create-events.d.ts +0 -3
  128. package/dist/maplibre/types/core/store.d.ts +0 -12
  129. package/dist/maplibre/types/core/use-canvas.d.ts +0 -11
  130. package/dist/maplibre/types/core/use-create-root.d.ts +0 -13
  131. package/dist/maplibre/types/core/use-on-add.d.ts +0 -10
  132. package/dist/maplibre/types/core/use-render.d.ts +0 -4
  133. package/dist/types/core/create-events.d.ts +0 -3
  134. package/dist/types/core/store.d.ts +0 -12
  135. package/dist/types/core/use-canvas.d.ts +0 -11
  136. package/dist/types/core/use-create-root.d.ts +0 -13
  137. package/dist/types/core/use-on-add.d.ts +0 -10
  138. package/dist/types/core/use-render.d.ts +0 -4
package/dist/cjs/main.js CHANGED
@@ -2,10 +2,12 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const fiber = require("@react-three/fiber");
4
4
  const jsxRuntime = require("react/jsx-runtime");
5
- const react = require("react");
6
- const THREE = require("three");
7
5
  const mapboxGl = require("mapbox-gl");
6
+ const react = require("react");
8
7
  const reactMapGl = require("react-map-gl");
8
+ const THREE = require("three");
9
+ const reactDom = require("react-dom");
10
+ const turf = require("@turf/turf");
9
11
  function _interopNamespaceDefault(e) {
10
12
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
11
13
  if (e) {
@@ -27,15 +29,14 @@ const useMap$1 = () => fiber.useThree((s) => {
27
29
  var _a;
28
30
  return (_a = s.r3m) == null ? void 0 : _a.map;
29
31
  });
30
- const useR3M = () => fiber.useThree((s) => s.r3m);
31
32
  const originMx = new THREE.Matrix4();
32
33
  const projByView = new THREE.Matrix4();
33
- const projByViewInv$1 = new THREE.Matrix4();
34
+ const projByViewInv = new THREE.Matrix4();
34
35
  const fwd = new THREE.Vector3();
35
36
  function syncCamera(camera, origin, mapCamMx) {
36
37
  projByView.fromArray(mapCamMx).multiply(originMx.fromArray(origin));
37
- projByViewInv$1.copy(projByView).invert();
38
- updateCamera(camera, projByViewInv$1);
38
+ projByViewInv.copy(projByView).invert();
39
+ updateCamera(camera, projByViewInv);
39
40
  camera.updateMatrix();
40
41
  camera.updateMatrixWorld(true);
41
42
  camera.projectionMatrix.copy(camera.matrix).premultiply(projByView);
@@ -46,7 +47,7 @@ function syncCamera(camera, origin, mapCamMx) {
46
47
  camera.near
47
48
  );
48
49
  camera.userData.projByView = projByView.toArray();
49
- camera.userData.projByViewInv = projByViewInv$1.toArray();
50
+ camera.userData.projByViewInv = projByViewInv.toArray();
50
51
  }
51
52
  const updateCamera = (target, projByViewInv2) => {
52
53
  target.position.setScalar(0).applyMatrix4(projByViewInv2);
@@ -65,7 +66,12 @@ const euler = new THREE.Euler();
65
66
  const pos = new THREE.Vector3();
66
67
  const scale = new THREE.Vector3();
67
68
  const m4 = new THREE.Matrix4();
68
- function coordsToMatrix({ longitude, latitude, altitude, fromLngLat: fromLngLat2 }) {
69
+ function coordsToMatrix({
70
+ longitude,
71
+ latitude,
72
+ altitude,
73
+ fromLngLat: fromLngLat2
74
+ }) {
69
75
  const center = fromLngLat2([longitude, latitude], altitude);
70
76
  const scaleUnit = center.meterInMercatorCoordinateUnits();
71
77
  pos.set(center.x, center.y, center.z || 0);
@@ -73,7 +79,7 @@ function coordsToMatrix({ longitude, latitude, altitude, fromLngLat: fromLngLat2
73
79
  quat.setFromEuler(euler.set(-Math.PI * 0.5, 0, 0));
74
80
  return m4.compose(pos, quat, scale).toArray();
75
81
  }
76
- function useCoords({ latitude, longitude, altitude, fromLngLat: fromLngLat2 }) {
82
+ function useCoordsToMatrix({ latitude, longitude, altitude, fromLngLat: fromLngLat2 }) {
77
83
  const m42 = react.useMemo(() => coordsToMatrix({
78
84
  latitude,
79
85
  longitude,
@@ -82,6 +88,23 @@ function useCoords({ latitude, longitude, altitude, fromLngLat: fromLngLat2 }) {
82
88
  }), [latitude, longitude, altitude, fromLngLat2]);
83
89
  return m42;
84
90
  }
91
+ function useR3M() {
92
+ const r3m = fiber.useThree((s) => s.r3m);
93
+ return r3m;
94
+ }
95
+ function useInitR3M(props) {
96
+ const canvas = fiber.useThree((s) => s.gl.domElement);
97
+ react.useState(() => {
98
+ const store = fiber._roots.get(canvas).store;
99
+ initR3M({ ...props, store });
100
+ });
101
+ }
102
+ function initR3M({ store, ...props }) {
103
+ const viewProjMx = new THREE.Matrix4().identity().toArray();
104
+ const r3m = { ...props, viewProjMx };
105
+ store.setState({ r3m });
106
+ return r3m;
107
+ }
85
108
  const Coordinates = react.memo(({
86
109
  latitude,
87
110
  longitude,
@@ -90,7 +113,7 @@ const Coordinates = react.memo(({
90
113
  }) => {
91
114
  const [scene] = react.useState(() => new THREE.Scene());
92
115
  const r3m = useR3M();
93
- const origin = useCoords({
116
+ const origin = useCoordsToMatrix({
94
117
  latitude,
95
118
  longitude,
96
119
  altitude,
@@ -106,11 +129,9 @@ function RenderAtCoords({ r3m, origin }) {
106
129
  const { gl, scene, set } = fiber.useThree();
107
130
  const cameraRef = react.useRef(null);
108
131
  fiber.useFrame(() => {
109
- if (!r3m.mapCamMx)
110
- return;
111
132
  if (!cameraRef.current)
112
133
  return;
113
- syncCamera(cameraRef.current, origin, r3m.mapCamMx);
134
+ syncCamera(cameraRef.current, origin, r3m.viewProjMx);
114
135
  gl.render(scene, cameraRef.current);
115
136
  });
116
137
  react.useLayoutEffect(() => {
@@ -127,71 +148,56 @@ function RenderAtCoords({ r3m, origin }) {
127
148
  }, [set, r3m]);
128
149
  return /* @__PURE__ */ jsxRuntime.jsx("perspectiveCamera", { ref: cameraRef });
129
150
  }
130
- const DOM_EVENTS = {
131
- onClick: ["click", false],
132
- onContextMenu: ["contextmenu", false],
133
- onDoubleClick: ["dblclick", false],
134
- onWheel: ["wheel", true],
135
- onPointerDown: ["pointerdown", true],
136
- onPointerUp: ["pointerup", true],
137
- onPointerLeave: ["pointerleave", true],
138
- onPointerMove: ["pointermove", true],
139
- onPointerCancel: ["pointercancel", true],
140
- onLostPointerCapture: ["lostpointercapture", true]
141
- };
142
- const projByViewInv = new THREE.Matrix4();
143
- function createEvents() {
144
- return (store) => {
145
- const { handlePointer } = fiber.createEvents(store);
146
- return {
147
- priority: 1,
148
- enabled: true,
149
- compute(event, state) {
150
- state.pointer.x = event.offsetX / state.size.width * 2 - 1;
151
- state.pointer.y = 1 - event.offsetY / state.size.height * 2;
152
- if (state.camera.userData.projByViewInv)
153
- projByViewInv.fromArray(state.camera.userData.projByViewInv);
154
- state.raycaster.camera = state.camera;
155
- state.raycaster.ray.origin.setScalar(0).applyMatrix4(projByViewInv);
156
- state.raycaster.ray.direction.set(state.pointer.x, state.pointer.y, 1).applyMatrix4(projByViewInv).sub(state.raycaster.ray.origin).normalize();
157
- },
158
- connected: void 0,
159
- handlers: Object.keys(DOM_EVENTS).reduce(
160
- (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
161
- {}
162
- ),
163
- update: () => {
164
- var _a;
165
- const { events, internal } = store.getState();
166
- if (((_a = internal.lastEvent) == null ? void 0 : _a.current) && events.handlers) {
167
- events.handlers.onPointerMove(internal.lastEvent.current);
168
- }
169
- },
170
- connect: (target) => {
171
- var _a;
172
- const { set, events } = store.getState();
173
- (_a = events.disconnect) == null ? void 0 : _a.call(events);
174
- set((state) => ({ events: { ...state.events, connected: target.parentNode } }));
175
- Object.entries(events.handlers ?? []).forEach(([name, event]) => {
176
- const [eventName, passive] = DOM_EVENTS[name];
177
- target.addEventListener(eventName, event, { passive });
178
- });
179
- },
180
- disconnect: () => {
181
- const { set, events } = store.getState();
182
- if (events.connected) {
183
- Object.entries(events.handlers ?? []).forEach(([name, event]) => {
184
- if (events && events.connected instanceof HTMLElement) {
185
- const [eventName] = DOM_EVENTS[name];
186
- events.connected.removeEventListener(eventName, event);
187
- }
188
- });
189
- set((state) => ({ events: { ...state.events, connected: void 0 } }));
190
- }
191
- }
192
- };
193
- };
151
+ function useCoords() {
152
+ const coords = fiber.useThree((s) => s.coords);
153
+ return coords;
154
+ }
155
+ function useSetCoords({ longitude, latitude, altitude }) {
156
+ const canvas = fiber.useThree((s) => s.gl.domElement);
157
+ react.useMemo(() => {
158
+ const store = fiber._roots.get(canvas).store;
159
+ const coords = { longitude, latitude, altitude };
160
+ setCoords(store, coords);
161
+ }, [longitude, latitude, altitude]);
162
+ }
163
+ function useSetRootCoords(store, {
164
+ longitude,
165
+ latitude,
166
+ altitude
167
+ }) {
168
+ react.useMemo(() => {
169
+ setCoords(store, { longitude, latitude, altitude });
170
+ }, [longitude, latitude, altitude]);
171
+ }
172
+ function setCoords(store, coords) {
173
+ store.setState({ coords });
194
174
  }
175
+ function coordsToVector3(point, origin) {
176
+ const originCoords = [origin.longitude, origin.latitude, origin.altitude || 0];
177
+ const pointCoords = [point.longitude, point.latitude, point.altitude || 0];
178
+ const dist = turf.distance(originCoords, pointCoords, { units: "meters" });
179
+ const angle = turf.bearing(originCoords, pointCoords);
180
+ const adjustedAngle = angle - 90;
181
+ const x = dist * Math.cos(adjustedAngle * THREE.MathUtils.DEG2RAD);
182
+ const y = (point.altitude || 0) - (origin.altitude || 0);
183
+ const z = dist * Math.sin(adjustedAngle * THREE.MathUtils.DEG2RAD);
184
+ const v3 = [x, y, z];
185
+ return v3;
186
+ }
187
+ const NearCoordinates = react.memo(({ children, ...coords }) => {
188
+ const { latitude, longitude, altitude } = useCoords();
189
+ const pos2 = react.useMemo(() => coordsToVector3(coords, { latitude, longitude, altitude }), [
190
+ // eslint-disable-line react-hooks/exhaustive-deps
191
+ latitude,
192
+ longitude,
193
+ altitude,
194
+ coords.latitude,
195
+ coords.longitude,
196
+ coords.altitude
197
+ ]);
198
+ return /* @__PURE__ */ jsxRuntime.jsx("object3D", { position: pos2, children });
199
+ });
200
+ NearCoordinates.displayName = "NearCoordinates";
195
201
  const useFunction = (callback) => {
196
202
  const callbackRef = react.useRef(callback);
197
203
  callbackRef.current = callback;
@@ -199,23 +205,62 @@ const useFunction = (callback) => {
199
205
  return callbackRef.current(...args);
200
206
  }, []);
201
207
  };
202
- function useOnAdd(fromLngLat2, { frameloop, ...renderProps }) {
203
- const [mounted, setMounted] = react.useState(false);
204
- const r3mRef = react.useRef({ fromLngLat: fromLngLat2 });
205
- const onAdd = useFunction((map, gl) => {
206
- const canvas = map.getCanvas();
207
- const root = fiber.createRoot(canvas);
208
- root.configure({
208
+ function useRender({
209
+ map,
210
+ origin,
211
+ useThree,
212
+ frameloop,
213
+ r3m
214
+ }) {
215
+ const render = useFunction((_gl, projViewMx) => {
216
+ r3m.viewProjMx.splice(0, 16, ...projViewMx);
217
+ const state = useThree.getState();
218
+ const camera = state.camera;
219
+ const { gl, advance } = state;
220
+ syncCamera(camera, origin, projViewMx);
221
+ gl.resetState();
222
+ advance(Date.now() * 1e-3, true);
223
+ if (!frameloop || frameloop === "always")
224
+ map.triggerRepaint();
225
+ });
226
+ return render;
227
+ }
228
+ const projViewInv = new THREE.Matrix4();
229
+ const events = (store) => {
230
+ const originalEvents = fiber.events(store);
231
+ return {
232
+ ...originalEvents,
233
+ connect: (target) => {
234
+ if (!originalEvents.connect)
235
+ return;
236
+ originalEvents.connect(target.parentElement);
237
+ },
238
+ compute: (event, state) => {
239
+ state.pointer.x = event.offsetX / state.size.width * 2 - 1;
240
+ state.pointer.y = 1 - event.offsetY / state.size.height * 2;
241
+ if (state.camera.userData.projByViewInv)
242
+ projViewInv.fromArray(state.camera.userData.projByViewInv);
243
+ state.raycaster.camera = state.camera;
244
+ state.raycaster.ray.origin.setScalar(0).applyMatrix4(projViewInv);
245
+ state.raycaster.ray.direction.set(state.pointer.x, state.pointer.y, 1).applyMatrix4(projViewInv).sub(state.raycaster.ray.origin).normalize();
246
+ }
247
+ };
248
+ };
249
+ function useRoot(fromLngLat2, map, { frameloop, longitude, latitude, altitude, ...props }) {
250
+ const [{ root, useThree, canvas, r3m }] = react.useState(() => {
251
+ const canvas2 = map.getCanvas();
252
+ const gl = canvas2.getContext("webgl2") || canvas2.getContext("webgl");
253
+ const root2 = fiber.createRoot(canvas2);
254
+ root2.configure({
209
255
  dpr: window.devicePixelRatio,
210
- events: createEvents(),
211
- ...renderProps,
256
+ events,
257
+ ...props,
212
258
  frameloop: "never",
213
259
  gl: {
214
260
  context: gl,
215
- depth: true,
216
261
  autoClear: false,
217
262
  antialias: true,
218
- ...renderProps == null ? void 0 : renderProps.gl
263
+ ...props == null ? void 0 : props.gl
219
264
  },
220
265
  onCreated: (state) => {
221
266
  state.gl.forceContextLoss = () => {
@@ -226,19 +271,17 @@ function useOnAdd(fromLngLat2, { frameloop, ...renderProps }) {
226
271
  near: 0
227
272
  },
228
273
  size: {
229
- width: canvas.clientWidth,
230
- height: canvas.clientHeight,
231
- top: 0,
232
- left: 0,
274
+ width: canvas2.clientWidth,
275
+ height: canvas2.clientHeight,
276
+ top: canvas2.offsetTop,
277
+ left: canvas2.offsetLeft,
233
278
  updateStyle: false,
234
- ...renderProps == null ? void 0 : renderProps.size
279
+ ...props == null ? void 0 : props.size
235
280
  }
236
281
  });
237
- const store = fiber._roots.get(canvas).store;
238
- r3mRef.current.map = map;
239
- r3mRef.current.root = root;
240
- r3mRef.current.state = store.getState();
241
- store.setState({ r3m: r3mRef.current });
282
+ const store = fiber._roots.get(canvas2).store;
283
+ const r3m2 = initR3M({ map, fromLngLat: fromLngLat2, store });
284
+ setCoords(store, { longitude, latitude, altitude });
242
285
  if (frameloop === "demand") {
243
286
  store.setState({
244
287
  frameloop,
@@ -247,111 +290,256 @@ function useOnAdd(fromLngLat2, { frameloop, ...renderProps }) {
247
290
  }
248
291
  });
249
292
  }
250
- map.on("resize", onResize);
251
- setTimeout(() => setMounted(true));
293
+ return { root: root2, useThree: store, map, canvas: canvas2, r3m: r3m2 };
252
294
  });
253
295
  const onResize = useFunction(() => {
254
- if (!r3mRef.current.map)
255
- return;
256
- if (!r3mRef.current.state)
257
- return;
258
- const map = r3mRef.current.map;
259
- const canvas = map.getCanvas();
260
- let updateDPR = canvas.classList.contains("mapboxgl-canvas");
261
- if (!updateDPR && map.getPixelRatio && map.getPixelRatio() === window.devicePixelRatio) {
262
- updateDPR = true;
263
- }
264
- if (updateDPR) {
265
- r3mRef.current.state.setDpr(window.devicePixelRatio);
266
- }
267
- r3mRef.current.state.setSize(
296
+ const { setDpr, setSize } = useThree.getState();
297
+ setDpr(window.devicePixelRatio);
298
+ setSize(
268
299
  canvas.clientWidth,
269
300
  canvas.clientHeight,
270
- false
301
+ false,
302
+ canvas.offsetTop,
303
+ canvas.offsetLeft
271
304
  );
272
305
  });
273
306
  const onRemove = useFunction(() => {
274
- if (!r3mRef.current.root)
275
- return;
276
- r3mRef.current.root.unmount();
277
- r3mRef.current.root = void 0;
278
- if (!r3mRef.current.map)
279
- return;
280
- r3mRef.current.map.off("resize", onResize);
307
+ root.unmount();
281
308
  });
282
- react.useEffect(() => () => onRemove(), [onRemove]);
283
- return { onAdd, onRemove, mounted, r3mRef };
284
- }
285
- const useCreateRoot = ({
286
- children,
287
- frameloop,
288
- fromLngLat: fromLngLat2,
289
- ...renderProps
290
- }) => {
291
- const id = react.useId();
292
- const { onAdd, onRemove, mounted, r3mRef } = useOnAdd(fromLngLat2, { frameloop, ...renderProps });
309
+ useSetRootCoords(useThree, { longitude, latitude, altitude });
293
310
  react.useEffect(() => {
294
- if (!mounted)
311
+ if (frameloop !== "demand")
295
312
  return;
296
- if (!r3mRef.current.root)
297
- return;
298
- r3mRef.current.root.render(/* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children }));
299
- }, [r3mRef, mounted, children]);
300
- return { id, onAdd, onRemove, r3mRef };
301
- };
302
- function useRender(origin, r3mRef, frameloop) {
303
- const render = useFunction((_gl, mapCamMx) => {
304
- const r3m = r3mRef.current;
305
- if (!r3m.state || !r3m.map)
306
- return;
307
- const camera = r3m.state.camera;
308
- const gl = r3m.state.gl;
309
- const advance = r3m.state.advance;
310
- r3m.mapCamMx = mapCamMx;
311
- syncCamera(camera, origin, mapCamMx);
312
- gl.resetState();
313
- advance(Date.now() * 1e-3, true);
314
- if (frameloop === "always")
315
- r3m.map.triggerRepaint();
316
- });
317
- return render;
313
+ const setState = useThree.setState;
314
+ const { invalidate } = useThree.getState();
315
+ setState({
316
+ frameloop,
317
+ invalidate: () => {
318
+ map.triggerRepaint();
319
+ }
320
+ });
321
+ return () => {
322
+ setState({ frameloop: "never", invalidate });
323
+ };
324
+ }, [frameloop]);
325
+ react.useEffect(() => {
326
+ map.on("resize", onResize);
327
+ return () => {
328
+ map.off("resize", onResize);
329
+ };
330
+ }, []);
331
+ react.useEffect(() => {
332
+ root.render(/* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children }));
333
+ }, [props.children]);
334
+ return { onRemove, useThree, r3m };
318
335
  }
319
- function useCanvas({
320
- longitude,
321
- latitude,
322
- altitude = 0,
323
- frameloop = "always",
324
- fromLngLat: fromLngLat2,
325
- ...renderProps
326
- }) {
327
- const m42 = useCoords({
336
+ function useCanvasInLayer(props, fromLngLat2, map) {
337
+ const { latitude, longitude, altitude, frameloop } = props;
338
+ const origin = useCoordsToMatrix({
328
339
  latitude,
329
340
  longitude,
330
341
  altitude,
331
342
  fromLngLat: fromLngLat2
332
343
  });
333
- const { id, onAdd, onRemove, r3mRef } = useCreateRoot({ frameloop, fromLngLat: fromLngLat2, ...renderProps });
334
- const render = useRender(m42, r3mRef, frameloop);
335
- return { id, onAdd, onRemove, render };
344
+ const { onRemove, useThree, r3m } = useRoot(fromLngLat2, map, props);
345
+ const render = useRender({ origin, frameloop, useThree, map, r3m });
346
+ return {
347
+ id: props.id,
348
+ beforeId: props.beforeId,
349
+ onRemove,
350
+ render,
351
+ type: "custom",
352
+ renderingMode: "3d"
353
+ };
336
354
  }
337
- fiber.extend(THREE__namespace);
338
- const fromLngLat = mapboxGl.MercatorCoordinate.fromLngLat;
339
- const Canvas = react.memo(({ id, beforeId, ...props }) => {
340
- const { id: reactId, onAdd, onRemove, render } = useCanvas({ ...props, fromLngLat });
341
- return /* @__PURE__ */ jsxRuntime.jsx(
342
- reactMapGl.Layer,
355
+ const InitR3M = react.memo(({
356
+ longitude,
357
+ latitude,
358
+ altitude,
359
+ ...props
360
+ }) => {
361
+ useInitR3M(props);
362
+ useSetCoords({ longitude, latitude, altitude });
363
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
364
+ });
365
+ InitR3M.displayName = "InitR3M";
366
+ const SyncCameraFC = react.memo(({
367
+ latitude,
368
+ longitude,
369
+ altitude = 0,
370
+ setOnRender,
371
+ manualRender,
372
+ onReady,
373
+ mapCanvas
374
+ }) => {
375
+ const r3m = useR3M();
376
+ const camRef = react.useRef(null);
377
+ const camera = fiber.useThree((s) => s.camera);
378
+ const gl = fiber.useThree((s) => s.gl);
379
+ const threeCanvas = fiber.useThree((s) => s.gl.domElement);
380
+ const scene = fiber.useThree((s) => s.scene);
381
+ const advance = fiber.useThree((s) => s.advance);
382
+ const setSize = fiber.useThree((s) => s.setSize);
383
+ const set = fiber.useThree((s) => s.set);
384
+ const origin = useCoordsToMatrix({ latitude, longitude, altitude, fromLngLat: r3m.fromLngLat });
385
+ const ready = react.useRef(false);
386
+ fiber.useFrame(() => {
387
+ syncCamera(camera, origin, r3m.viewProjMx);
388
+ if (!manualRender)
389
+ return;
390
+ gl.render(scene, camera);
391
+ }, -Infinity);
392
+ const onRender = useFunction((viewProjMx) => {
393
+ if (threeCanvas.width !== mapCanvas.width || threeCanvas.height !== mapCanvas.height) {
394
+ setSize(
395
+ mapCanvas.clientWidth,
396
+ mapCanvas.clientHeight,
397
+ true,
398
+ mapCanvas.offsetTop,
399
+ mapCanvas.offsetLeft
400
+ );
401
+ }
402
+ r3m.viewProjMx = viewProjMx;
403
+ if (!ready.current && onReady) {
404
+ ready.current = true;
405
+ onReady();
406
+ }
407
+ advance(Date.now() * 1e-3, true);
408
+ });
409
+ react.useEffect(() => {
410
+ setOnRender && setOnRender(() => onRender);
411
+ }, [setOnRender, onRender]);
412
+ react.useLayoutEffect(() => {
413
+ if (!manualRender)
414
+ return;
415
+ set({ camera: camRef.current });
416
+ }, []);
417
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: manualRender && /* @__PURE__ */ jsxRuntime.jsx(
418
+ "perspectiveCamera",
419
+ {
420
+ ref: camRef,
421
+ matrixAutoUpdate: false,
422
+ matrixWorldAutoUpdate: false
423
+ }
424
+ ) });
425
+ });
426
+ SyncCameraFC.displayName = "SyncCameraFC";
427
+ const CanvasPortal = react.memo(({
428
+ children,
429
+ latitude,
430
+ longitude,
431
+ altitude,
432
+ setOnRender,
433
+ map,
434
+ fromLngLat: fromLngLat2,
435
+ ...props
436
+ }) => {
437
+ const mapCanvas = map.getCanvas();
438
+ const eventSource = mapCanvas.parentElement;
439
+ const [ready, setReady] = react.useState(false);
440
+ const onReady = useFunction(() => {
441
+ setReady(true);
442
+ });
443
+ return /* @__PURE__ */ jsxRuntime.jsxs(
444
+ fiber.Canvas,
343
445
  {
344
- id: id || reactId,
345
- beforeId,
346
- type: "custom",
347
- renderingMode: "3d",
348
- onAdd,
349
- onRemove,
350
- render
446
+ camera: {
447
+ matrixAutoUpdate: false,
448
+ matrixWorldAutoUpdate: false
449
+ },
450
+ events,
451
+ eventSource,
452
+ ...props,
453
+ gl: { autoClear: false, ...props.gl },
454
+ children: [
455
+ /* @__PURE__ */ jsxRuntime.jsx(
456
+ InitR3M,
457
+ {
458
+ map,
459
+ fromLngLat: fromLngLat2,
460
+ latitude,
461
+ longitude,
462
+ altitude
463
+ }
464
+ ),
465
+ /* @__PURE__ */ jsxRuntime.jsx(
466
+ SyncCameraFC,
467
+ {
468
+ latitude,
469
+ longitude,
470
+ altitude,
471
+ setOnRender,
472
+ onReady,
473
+ mapCanvas
474
+ }
475
+ ),
476
+ ready && children
477
+ ]
351
478
  }
352
479
  );
353
480
  });
481
+ CanvasPortal.displayName = "CanvasPortal";
482
+ const InitCanvasFC = react.memo((props) => {
483
+ const canvas = props.map.getCanvas();
484
+ const [el] = react.useState(() => {
485
+ const el2 = document.createElement("div");
486
+ el2.style.position = "absolute";
487
+ el2.style.top = "0";
488
+ el2.style.bottom = "0";
489
+ el2.style.left = "0";
490
+ el2.style.right = "0";
491
+ el2.style.pointerEvents = "none";
492
+ return el2;
493
+ });
494
+ react.useEffect(() => {
495
+ const parent = canvas.parentElement;
496
+ parent.appendChild(el);
497
+ return () => {
498
+ parent.removeChild(el);
499
+ };
500
+ }, []);
501
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: reactDom.createPortal(/* @__PURE__ */ jsxRuntime.jsx(CanvasPortal, { ...props }), el) });
502
+ });
503
+ InitCanvasFC.displayName = "InitCanvasFC";
504
+ fiber.extend(THREE__namespace);
505
+ const fromLngLat = mapboxGl.MercatorCoordinate.fromLngLat;
506
+ const Canvas = react.memo(({ overlay, ...props }) => {
507
+ const map = reactMapGl.useMap().current.getMap();
508
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
509
+ overlay && /* @__PURE__ */ jsxRuntime.jsx(CanvasOverlay, { map, ...props }),
510
+ !overlay && /* @__PURE__ */ jsxRuntime.jsx(CanvasInLayer, { map, ...props })
511
+ ] });
512
+ });
513
+ Canvas.displayName = "Canvas";
514
+ const CanvasInLayer = react.memo(({ map, ...props }) => {
515
+ const layerProps = useCanvasInLayer(props, fromLngLat, map);
516
+ return /* @__PURE__ */ jsxRuntime.jsx(reactMapGl.Layer, { ...layerProps });
517
+ });
518
+ CanvasInLayer.displayName = "CanvasInLayer";
519
+ const CanvasOverlay = react.memo(({ map, id, beforeId, ...props }) => {
520
+ const [onRender, setOnRender] = react.useState();
521
+ const render = useFunction((_gl, mx) => {
522
+ if (!onRender)
523
+ return;
524
+ onRender(mx);
525
+ });
526
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
527
+ /* @__PURE__ */ jsxRuntime.jsx(reactMapGl.Layer, { id, beforeId, type: "custom", render }),
528
+ /* @__PURE__ */ jsxRuntime.jsx(
529
+ InitCanvasFC,
530
+ {
531
+ ...props,
532
+ setOnRender,
533
+ map,
534
+ fromLngLat
535
+ }
536
+ )
537
+ ] });
538
+ });
539
+ CanvasInLayer.displayName = "CanvasInLayer";
354
540
  const useMap = useMap$1;
355
541
  exports.Canvas = Canvas;
356
542
  exports.Coordinates = Coordinates;
543
+ exports.NearCoordinates = NearCoordinates;
544
+ exports.coordsToVector3 = coordsToVector3;
357
545
  exports.useMap = useMap;
package/dist/es/main.mjs CHANGED
@@ -1,10 +1,14 @@
1
1
  import { useMap as useMap$1 } from "./main2.mjs";
2
- import { Coordinates } from "./main3.mjs";
3
- import { Canvas } from "./main4.mjs";
2
+ import { Canvas } from "./main3.mjs";
3
+ import { Coordinates } from "./main4.mjs";
4
+ import { NearCoordinates } from "./main5.mjs";
5
+ import { coordsToVector3 } from "./main6.mjs";
4
6
  const useMap = useMap$1;
5
7
  export {
6
8
  Canvas,
7
9
  Coordinates,
10
+ NearCoordinates,
11
+ coordsToVector3,
8
12
  useMap
9
13
  };
10
14
  //# sourceMappingURL=main.mjs.map