@react-three/fiber 8.0.0-beta.5 → 8.0.0-beta.6

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.
@@ -15,6 +15,15 @@ const isDiffSet = def => def && !!def.memoized && !!def.changes;
15
15
  function calculateDpr(dpr) {
16
16
  return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], window.devicePixelRatio), dpr[1]) : dpr;
17
17
  }
18
+ /**
19
+ * Returns instance root state
20
+ */
21
+
22
+ const getRootState = obj => {
23
+ var _r3f;
24
+
25
+ return (_r3f = obj.__r3f) == null ? void 0 : _r3f.root.getState();
26
+ };
18
27
  /**
19
28
  * Picks or omits keys from an object
20
29
  * `omit` will filter out keys, and otherwise cherry-pick them.
@@ -24,11 +33,7 @@ function filterKeys(obj, omit, ...keys) {
24
33
  const keysToSelect = new Set(keys);
25
34
  return Object.entries(obj).reduce((acc, [key, value]) => {
26
35
  const shouldInclude = !omit;
27
-
28
- if (keysToSelect.has(key) === shouldInclude) {
29
- acc[key] = value;
30
- }
31
-
36
+ if (keysToSelect.has(key) === shouldInclude) acc[key] = value;
32
37
  return acc;
33
38
  }, {});
34
39
  }
@@ -382,6 +387,7 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
382
387
 
383
388
  function removeInteractivity(store, object) {
384
389
  const {
390
+ events,
385
391
  internal
386
392
  } = store.getState(); // Removes every trace of an object from the data store
387
393
 
@@ -389,6 +395,7 @@ function removeInteractivity(store, object) {
389
395
  internal.initialHits = internal.initialHits.filter(o => o !== object);
390
396
  internal.hovered.forEach((value, key) => {
391
397
  if (value.eventObject === object || value.object === object) {
398
+ // Clear out intersects, they are outdated by now
392
399
  internal.hovered.delete(key);
393
400
  }
394
401
  });
@@ -398,31 +405,8 @@ function removeInteractivity(store, object) {
398
405
  }
399
406
  function createEvents(store) {
400
407
  const temp = new THREE.Vector3();
401
- /** Sets up defaultRaycaster */
402
-
403
- function prepareRay(event) {
404
- var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
405
-
406
- const state = store.getState();
407
- const {
408
- raycaster,
409
- mouse,
410
- camera,
411
- size
412
- } = state; // https://github.com/pmndrs/react-three-fiber/pull/782
413
- // Events trigger outside of canvas when moved
414
-
415
- const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
416
- const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
417
- const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
418
- const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
419
- const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
420
- mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
421
- raycaster.setFromCamera(mouse, camera);
422
- }
423
408
  /** Calculates delta */
424
409
 
425
-
426
410
  function calculateDistance(event) {
427
411
  const {
428
412
  internal
@@ -442,55 +426,70 @@ function createEvents(store) {
442
426
  }));
443
427
  }
444
428
 
445
- function intersect(filter) {
429
+ function intersect(event, filter) {
446
430
  const state = store.getState();
447
- const {
448
- raycaster,
449
- internal
450
- } = state; // Skip event handling when noEvents is set
451
-
452
- if (!raycaster.enabled) return [];
453
- const seen = new Set();
431
+ const duplicates = new Set();
454
432
  const intersections = []; // Allow callers to eliminate event objects
455
433
 
456
- const eventsObjects = filter ? filter(internal.interaction) : internal.interaction; // Intersect known handler objects and filter against duplicates
434
+ const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction; // Reset all raycaster cameras to undefined
435
+
436
+ eventsObjects.forEach(obj => {
437
+ const state = getRootState(obj);
438
+
439
+ if (state) {
440
+ state.raycaster.camera = undefined;
441
+ }
442
+ }); // Collect events
443
+
444
+ let hits = eventsObjects // Intersect objects
445
+ .flatMap(obj => {
446
+ const state = getRootState(obj); // Skip event handling when noEvents is set, or when the raycasters camera is null
447
+
448
+ if (!state || !state.events.enabled || state.raycaster.camera === null) return []; // When the camera is undefined we have to call the event layers update function
449
+
450
+ if (state.raycaster.camera === undefined) {
451
+ var _state$previousRoot;
452
+
453
+ state.events.compute == null ? void 0 : state.events.compute(event, state, (_state$previousRoot = state.previousRoot) == null ? void 0 : _state$previousRoot.getState()); // If the camera is still undefined we have to skip this layer entirely
457
454
 
458
- let intersects = raycaster.intersectObjects(eventsObjects, true).filter(item => {
455
+ if (state.raycaster.camera === undefined) state.raycaster.camera = null;
456
+ } // Intersect object by object
457
+
458
+
459
+ return state.raycaster.camera ? state.raycaster.intersectObject(obj, true) : [];
460
+ }) // Sort by event priority and distance
461
+ .sort((a, b) => {
462
+ const aState = getRootState(a.object);
463
+ const bState = getRootState(b.object);
464
+ if (!aState || !bState) return 0;
465
+ return bState.events.priority - aState.events.priority || a.distance - b.distance;
466
+ }) // Filter out duplicates
467
+ .filter(item => {
459
468
  const id = makeId(item);
460
- if (seen.has(id)) return false;
461
- seen.add(id);
469
+ if (duplicates.has(id)) return false;
470
+ duplicates.add(id);
462
471
  return true;
463
472
  }); // https://github.com/mrdoob/three.js/issues/16031
464
- // Allow custom userland intersect sort order
473
+ // Allow custom userland intersect sort order, this likely only makes sense on the root filter
465
474
 
466
- if (raycaster.filter) intersects = raycaster.filter(intersects, state);
475
+ if (state.events.filter) hits = state.events.filter(hits, state); // Bubble up the events, find the event source (eventObject)
467
476
 
468
- for (const intersect of intersects) {
469
- let eventObject = intersect.object; // Bubble event up
477
+ for (const hit of hits) {
478
+ let eventObject = hit.object; // Bubble event up
470
479
 
471
480
  while (eventObject) {
472
481
  var _r3f2;
473
482
 
474
- if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...intersect,
483
+ if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
475
484
  eventObject
476
485
  });
477
486
  eventObject = eventObject.parent;
478
487
  }
479
- }
488
+ } // If the interaction is captured, make all capturing targets part of the intersect.
480
489
 
481
- return intersections;
482
- }
483
- /** Creates filtered intersects and returns an array of positive hits */
484
-
485
-
486
- function patchIntersects(intersections, event) {
487
- const {
488
- internal
489
- } = store.getState(); // If the interaction is captured, make all capturing targets part of the
490
- // intersect.
491
490
 
492
- if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
493
- for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
491
+ if ('pointerId' in event && state.internal.capturedMap.has(event.pointerId)) {
492
+ for (let captureData of state.internal.capturedMap.get(event.pointerId).values()) {
494
493
  intersections.push(captureData.intersection);
495
494
  }
496
495
  }
@@ -503,13 +502,13 @@ function createEvents(store) {
503
502
  function handleIntersects(intersections, event, delta, callback) {
504
503
  const {
505
504
  raycaster,
506
- mouse,
505
+ pointer,
507
506
  camera,
508
507
  internal
509
508
  } = store.getState(); // If anything has been found, forward it to the event listeners
510
509
 
511
510
  if (intersections.length) {
512
- const unprojectedPoint = temp.set(mouse.x, mouse.y, 0).unproject(camera);
511
+ const unprojectedPoint = temp.set(pointer.x, pointer.y, 0).unproject(camera);
513
512
  const localState = {
514
513
  stopped: false
515
514
  };
@@ -560,8 +559,7 @@ function createEvents(store) {
560
559
 
561
560
  let raycastEvent = { ...hit,
562
561
  ...extractEventProps,
563
- spaceX: mouse.x,
564
- spaceY: mouse.y,
562
+ pointer,
565
563
  intersections,
566
564
  stopped: localState.stopped,
567
565
  delta,
@@ -598,8 +596,6 @@ function createEvents(store) {
598
596
  setPointerCapture,
599
597
  releasePointerCapture
600
598
  },
601
- sourceEvent: event,
602
- // deprecated
603
599
  nativeEvent: event
604
600
  }; // Call subscribers
605
601
 
@@ -664,14 +660,15 @@ function createEvents(store) {
664
660
  const {
665
661
  onPointerMissed,
666
662
  internal
667
- } = store.getState();
668
- prepareRay(event);
663
+ } = store.getState(); //prepareRay(event)
664
+
669
665
  internal.lastEvent.current = event; // Get fresh intersects
670
666
 
671
667
  const isPointerMove = name === 'onPointerMove';
672
668
  const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
673
- const filter = isPointerMove ? filterPointerEvents : undefined;
674
- const hits = patchIntersects(intersect(filter), event);
669
+ const filter = isPointerMove ? filterPointerEvents : undefined; //const hits = patchIntersects(intersect(filter), event)
670
+
671
+ const hits = intersect(event, filter);
675
672
  const delta = isClickEvent ? calculateDistance(event) : 0; // Save initial coordinates on pointer-down
676
673
 
677
674
  if (name === 'onPointerDown') {
@@ -1151,16 +1148,18 @@ const createStore = (invalidate, advance) => {
1151
1148
  }));
1152
1149
 
1153
1150
  return {
1151
+ set,
1152
+ get,
1154
1153
  // Mock objects that have to be configured
1155
1154
  gl: null,
1156
1155
  camera: null,
1157
1156
  raycaster: null,
1158
1157
  events: {
1158
+ priority: 1,
1159
+ enabled: true,
1159
1160
  connected: false
1160
1161
  },
1161
1162
  xr: null,
1162
- set,
1163
- get,
1164
1163
  invalidate: () => invalidate(get()),
1165
1164
  advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
1166
1165
  linear: false,
@@ -1168,7 +1167,7 @@ const createStore = (invalidate, advance) => {
1168
1167
  scene: prepare(new THREE.Scene()),
1169
1168
  controls: null,
1170
1169
  clock: new THREE.Clock(),
1171
- mouse: new THREE.Vector2(),
1170
+ pointer: new THREE.Vector2(),
1172
1171
  frameloop: 'always',
1173
1172
  onPointerMissed: undefined,
1174
1173
  performance: {
@@ -1237,6 +1236,7 @@ const createStore = (invalidate, advance) => {
1237
1236
  frameloop
1238
1237
  }));
1239
1238
  },
1239
+ previousRoot: undefined,
1240
1240
  internal: {
1241
1241
  active: false,
1242
1242
  priority: 0,
@@ -1438,43 +1438,6 @@ function useStore() {
1438
1438
  function useThree(selector = state => state, equalityFn) {
1439
1439
  return useStore()(selector, equalityFn);
1440
1440
  }
1441
- function useInject(state) {
1442
- const useOriginalStore = useStore();
1443
- const useInjectStore = React.useMemo(() => {
1444
- const useInjected = (sel = state => state) => {
1445
- // Execute the useStore hook with the selector once, to maintain reactivity, result doesn't matter
1446
- useOriginalStore(sel); // Inject data and return the result, either selected or raw
1447
-
1448
- return sel({ ...useOriginalStore.getState(),
1449
- ...state
1450
- });
1451
- };
1452
-
1453
- useInjected.setState = useOriginalStore.setState;
1454
- useInjected.destroy = useOriginalStore.destroy; // Patch getState
1455
-
1456
- useInjected.getState = () => {
1457
- return { ...useOriginalStore.getState(),
1458
- ...state
1459
- };
1460
- }; // Patch subscribe
1461
-
1462
-
1463
- useInjected.subscribe = listener => {
1464
- return useOriginalStore.subscribe((current, previous) => listener({ ...current,
1465
- ...state
1466
- }, previous));
1467
- };
1468
-
1469
- return useInjected;
1470
- }, [useOriginalStore, state]); // Return the patched store and a provider component
1471
-
1472
- return React.useMemo(() => [({
1473
- children
1474
- }) => /*#__PURE__*/React.createElement(context.Provider, {
1475
- value: useInjectStore
1476
- }, children), useInjectStore], [useInjectStore]);
1477
- }
1478
1441
  function useFrame(callback, renderPriority = 0) {
1479
1442
  const subscribe = useStore().getState().internal.subscribe; // Update ref
1480
1443
 
@@ -1501,6 +1464,11 @@ function loadingFn(extensions, onProgress) {
1501
1464
  };
1502
1465
  }
1503
1466
 
1467
+ function useMemoizedFn(fn) {
1468
+ const fnRef = React.useRef(fn);
1469
+ React.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
1470
+ return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
1471
+ }
1504
1472
  function useLoader(Proto, input, extensions, onProgress) {
1505
1473
  // Use suspense to load async assets
1506
1474
  const keys = Array.isArray(input) ? input : [input];
@@ -1600,9 +1568,7 @@ function createRoot(canvas) {
1600
1568
  params,
1601
1569
  ...options
1602
1570
  } = raycastOptions || {};
1603
- if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
1604
- enabled: true,
1605
- ...options
1571
+ if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
1606
1572
  });
1607
1573
  if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
1608
1574
  params: { ...raycaster.params,
@@ -1756,9 +1722,10 @@ function Provider({
1756
1722
  internal: { ...state.internal,
1757
1723
  active: true
1758
1724
  }
1759
- })); // Connect events
1725
+ })); // Connect events to the targets parent, this is done to ensure events are registered on
1726
+ // a shared target, and not on the canvas itself
1760
1727
 
1761
- state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
1728
+ state.events.connect == null ? void 0 : state.events.connect(target.parentNode); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
1762
1729
 
1763
1730
  if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
1764
1731
  }, []);
@@ -1805,20 +1772,56 @@ function createPortal(children, container, state) {
1805
1772
  }
1806
1773
 
1807
1774
  function Portal({
1808
- state,
1775
+ state = {},
1809
1776
  children,
1810
1777
  container
1811
1778
  }) {
1812
1779
  /** This has to be a component because it would not be able to call useThree/useStore otherwise since
1813
- * if this is our environment, then we are in in r3f's renderer but in react-dom, it would trigger
1780
+ * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
1814
1781
  * the "R3F hooks can only be used within the Canvas component!" warning:
1815
1782
  * <Canvas>
1816
1783
  * {createPortal(...)} */
1817
- const portalState = React.useMemo(() => ({ ...state,
1818
- scene: container
1819
- }), [state, container]);
1820
- const [PortalProvider, portalRoot] = useInject(portalState);
1821
- return /*#__PURE__*/React.createElement(React.Fragment, null, reconciler.createPortal( /*#__PURE__*/React.createElement(PortalProvider, null, children), portalRoot, null));
1784
+ const {
1785
+ events,
1786
+ ...rest
1787
+ } = state;
1788
+ const previousRoot = useStore();
1789
+ const [raycaster] = React.useState(() => new THREE.Raycaster());
1790
+ const inject = React.useCallback((state, injectState) => {
1791
+ const intersect = { ...state
1792
+ };
1793
+
1794
+ if (injectState) {
1795
+ // Only the fields of "state" that do not differ from injectState
1796
+ Object.keys(state).forEach(key => {
1797
+ if (state[key] !== injectState[key]) delete intersect[key];
1798
+ });
1799
+ }
1800
+
1801
+ return { ...intersect,
1802
+ scene: container,
1803
+ previousRoot,
1804
+ raycaster,
1805
+ events: { ...state.events,
1806
+ ...events
1807
+ },
1808
+ ...rest
1809
+ };
1810
+ }, [state]);
1811
+ const [useInjectStore] = React.useState(() => {
1812
+ const store = create((set, get) => ({ ...inject(previousRoot.getState()),
1813
+ set,
1814
+ get
1815
+ }));
1816
+ previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
1817
+ return store;
1818
+ });
1819
+ React.useEffect(() => {
1820
+ useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
1821
+ }, [inject]);
1822
+ return /*#__PURE__*/React.createElement(React.Fragment, null, reconciler.createPortal( /*#__PURE__*/React.createElement(context.Provider, {
1823
+ value: useInjectStore
1824
+ }, children), useInjectStore, null));
1822
1825
  }
1823
1826
 
1824
1827
  reconciler.injectIntoDevTools({
@@ -1828,4 +1831,4 @@ reconciler.injectIntoDevTools({
1828
1831
  });
1829
1832
  const act = React.unstable_act;
1830
1833
 
1831
- export { createRoot as a, context as b, createEvents as c, createPortal as d, extend as e, reconciler as f, applyProps as g, dispose as h, invalidate as i, advance as j, addEffect as k, addAfterEffect as l, addTail as m, act as n, omit as o, pick as p, roots as q, render as r, useStore as s, threeTypes as t, unmountComponentAtNode as u, useThree as v, useInject as w, useFrame as x, useGraph as y, useLoader as z };
1834
+ export { useLoader as A, createRoot as a, unmountComponentAtNode as b, createEvents as c, context as d, extend as e, createPortal as f, reconciler as g, applyProps as h, dispose as i, invalidate as j, advance as k, addEffect as l, addAfterEffect as m, addTail as n, omit as o, pick as p, getRootState as q, render as r, act as s, threeTypes as t, useMemoizedFn as u, roots as v, useStore as w, useThree as x, useFrame as y, useGraph as z };
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-5dc2de40.cjs.dev.js');
5
+ var index = require('./index-4782ba04.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -58,7 +58,17 @@ function createPointerEvents(store) {
58
58
  handlePointer
59
59
  } = index.createEvents(store);
60
60
  return {
61
- connected: false,
61
+ priority: 1,
62
+ enabled: true,
63
+
64
+ compute(event, state, previous) {
65
+ // https://github.com/pmndrs/react-three-fiber/pull/782
66
+ // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
67
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
68
+ state.raycaster.setFromCamera(state.pointer, state.camera);
69
+ },
70
+
71
+ connected: undefined,
62
72
  handlers: Object.keys(DOM_EVENTS).reduce((acc, key) => ({ ...acc,
63
73
  [key]: handlePointer(key)
64
74
  }), {}),
@@ -99,7 +109,7 @@ function createPointerEvents(store) {
99
109
  });
100
110
  set(state => ({
101
111
  events: { ...state.events,
102
- connected: false
112
+ connected: undefined
103
113
  }
104
114
  }));
105
115
  }
@@ -153,6 +163,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
153
163
  // This will include the entire THREE namespace by default, users can extend
154
164
  // their own elements by using the createRoot API instead
155
165
  React__namespace.useMemo(() => index.extend(THREE__namespace), []);
166
+ const onPointerMissed = index.useMemoizedFn(props.onPointerMissed);
156
167
  const [containerRef, {
157
168
  width,
158
169
  height
@@ -166,8 +177,12 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
166
177
  });
167
178
  const canvasRef = React__namespace.useRef(null);
168
179
  const [canvas, setCanvas] = React__namespace.useState(null);
169
- const canvasProps = index.pick(props, CANVAS_PROPS);
170
- const divProps = index.omit(props, CANVAS_PROPS);
180
+ const canvasProps = index.pick({ ...props,
181
+ onPointerMissed
182
+ }, CANVAS_PROPS);
183
+ const divProps = index.omit({ ...props,
184
+ onPointerMissed
185
+ }, CANVAS_PROPS);
171
186
  const [block, setBlock] = React__namespace.useState(false);
172
187
  const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
173
188
 
@@ -230,14 +245,15 @@ exports.createPortal = index.createPortal;
230
245
  exports.createRoot = index.createRoot;
231
246
  exports.dispose = index.dispose;
232
247
  exports.extend = index.extend;
248
+ exports.getRootState = index.getRootState;
233
249
  exports.invalidate = index.invalidate;
234
250
  exports.reconciler = index.reconciler;
235
251
  exports.render = index.render;
236
252
  exports.unmountComponentAtNode = index.unmountComponentAtNode;
237
253
  exports.useFrame = index.useFrame;
238
254
  exports.useGraph = index.useGraph;
239
- exports.useInject = index.useInject;
240
255
  exports.useLoader = index.useLoader;
256
+ exports.useMemoizedFn = index.useMemoizedFn;
241
257
  exports.useStore = index.useStore;
242
258
  exports.useThree = index.useThree;
243
259
  exports.Canvas = Canvas;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-e2a317e2.cjs.prod.js');
5
+ var index = require('./index-45f5b2a2.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -58,7 +58,17 @@ function createPointerEvents(store) {
58
58
  handlePointer
59
59
  } = index.createEvents(store);
60
60
  return {
61
- connected: false,
61
+ priority: 1,
62
+ enabled: true,
63
+
64
+ compute(event, state, previous) {
65
+ // https://github.com/pmndrs/react-three-fiber/pull/782
66
+ // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
67
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
68
+ state.raycaster.setFromCamera(state.pointer, state.camera);
69
+ },
70
+
71
+ connected: undefined,
62
72
  handlers: Object.keys(DOM_EVENTS).reduce((acc, key) => ({ ...acc,
63
73
  [key]: handlePointer(key)
64
74
  }), {}),
@@ -99,7 +109,7 @@ function createPointerEvents(store) {
99
109
  });
100
110
  set(state => ({
101
111
  events: { ...state.events,
102
- connected: false
112
+ connected: undefined
103
113
  }
104
114
  }));
105
115
  }
@@ -153,6 +163,7 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
153
163
  // This will include the entire THREE namespace by default, users can extend
154
164
  // their own elements by using the createRoot API instead
155
165
  React__namespace.useMemo(() => index.extend(THREE__namespace), []);
166
+ const onPointerMissed = index.useMemoizedFn(props.onPointerMissed);
156
167
  const [containerRef, {
157
168
  width,
158
169
  height
@@ -166,8 +177,12 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
166
177
  });
167
178
  const canvasRef = React__namespace.useRef(null);
168
179
  const [canvas, setCanvas] = React__namespace.useState(null);
169
- const canvasProps = index.pick(props, CANVAS_PROPS);
170
- const divProps = index.omit(props, CANVAS_PROPS);
180
+ const canvasProps = index.pick({ ...props,
181
+ onPointerMissed
182
+ }, CANVAS_PROPS);
183
+ const divProps = index.omit({ ...props,
184
+ onPointerMissed
185
+ }, CANVAS_PROPS);
171
186
  const [block, setBlock] = React__namespace.useState(false);
172
187
  const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
173
188
 
@@ -230,14 +245,15 @@ exports.createPortal = index.createPortal;
230
245
  exports.createRoot = index.createRoot;
231
246
  exports.dispose = index.dispose;
232
247
  exports.extend = index.extend;
248
+ exports.getRootState = index.getRootState;
233
249
  exports.invalidate = index.invalidate;
234
250
  exports.reconciler = index.reconciler;
235
251
  exports.render = index.render;
236
252
  exports.unmountComponentAtNode = index.unmountComponentAtNode;
237
253
  exports.useFrame = index.useFrame;
238
254
  exports.useGraph = index.useGraph;
239
- exports.useInject = index.useInject;
240
255
  exports.useLoader = index.useLoader;
256
+ exports.useMemoizedFn = index.useMemoizedFn;
241
257
  exports.useStore = index.useStore;
242
258
  exports.useThree = index.useThree;
243
259
  exports.Canvas = Canvas;
@@ -1,5 +1,5 @@
1
- import { c as createEvents, e as extend, p as pick, o as omit, a as createRoot, u as unmountComponentAtNode } from './index-32069e53.esm.js';
2
- export { t as ReactThreeFiber, q as _roots, n as act, l as addAfterEffect, k as addEffect, m as addTail, j as advance, g as applyProps, b as context, d as createPortal, a as createRoot, h as dispose, e as extend, i as invalidate, f as reconciler, r as render, u as unmountComponentAtNode, x as useFrame, y as useGraph, w as useInject, z as useLoader, s as useStore, v as useThree } from './index-32069e53.esm.js';
1
+ import { c as createEvents, e as extend, u as useMemoizedFn, p as pick, o as omit, a as createRoot, b as unmountComponentAtNode } from './index-74b1fd6b.esm.js';
2
+ export { t as ReactThreeFiber, v as _roots, s as act, m as addAfterEffect, l as addEffect, n as addTail, k as advance, h as applyProps, d as context, f as createPortal, a as createRoot, i as dispose, e as extend, q as getRootState, j as invalidate, g as reconciler, r as render, b as unmountComponentAtNode, y as useFrame, z as useGraph, A as useLoader, u as useMemoizedFn, w as useStore, x as useThree } from './index-74b1fd6b.esm.js';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
@@ -28,7 +28,17 @@ function createPointerEvents(store) {
28
28
  handlePointer
29
29
  } = createEvents(store);
30
30
  return {
31
- connected: false,
31
+ priority: 1,
32
+ enabled: true,
33
+
34
+ compute(event, state, previous) {
35
+ // https://github.com/pmndrs/react-three-fiber/pull/782
36
+ // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
37
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
38
+ state.raycaster.setFromCamera(state.pointer, state.camera);
39
+ },
40
+
41
+ connected: undefined,
32
42
  handlers: Object.keys(DOM_EVENTS).reduce((acc, key) => ({ ...acc,
33
43
  [key]: handlePointer(key)
34
44
  }), {}),
@@ -69,7 +79,7 @@ function createPointerEvents(store) {
69
79
  });
70
80
  set(state => ({
71
81
  events: { ...state.events,
72
- connected: false
82
+ connected: undefined
73
83
  }
74
84
  }));
75
85
  }
@@ -123,6 +133,7 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
123
133
  // This will include the entire THREE namespace by default, users can extend
124
134
  // their own elements by using the createRoot API instead
125
135
  React.useMemo(() => extend(THREE), []);
136
+ const onPointerMissed = useMemoizedFn(props.onPointerMissed);
126
137
  const [containerRef, {
127
138
  width,
128
139
  height
@@ -136,8 +147,12 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
136
147
  });
137
148
  const canvasRef = React.useRef(null);
138
149
  const [canvas, setCanvas] = React.useState(null);
139
- const canvasProps = pick(props, CANVAS_PROPS);
140
- const divProps = omit(props, CANVAS_PROPS);
150
+ const canvasProps = pick({ ...props,
151
+ onPointerMissed
152
+ }, CANVAS_PROPS);
153
+ const divProps = omit({ ...props,
154
+ onPointerMissed
155
+ }, CANVAS_PROPS);
141
156
  const [block, setBlock] = React.useState(false);
142
157
  const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
143
158