@react-three/fiber 8.0.0-beta.5 → 8.0.0-beta.8
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/dist/declarations/src/core/events.d.ts +11 -6
- package/dist/declarations/src/core/hooks.d.ts +6 -6
- package/dist/declarations/src/core/index.d.ts +13 -5
- package/dist/declarations/src/core/store.d.ts +12 -21
- package/dist/declarations/src/core/utils.d.ts +2 -1
- package/dist/{index-5dc2de40.cjs.dev.js → index-2056f0b6.cjs.dev.js} +144 -131
- package/dist/{index-32069e53.esm.js → index-3238fd12.esm.js} +143 -131
- package/dist/{index-e2a317e2.cjs.prod.js → index-f5108bb9.cjs.prod.js} +144 -131
- package/dist/react-three-fiber.cjs.dev.js +28 -7
- package/dist/react-three-fiber.cjs.prod.js +28 -7
- package/dist/react-three-fiber.esm.js +27 -7
- package/native/dist/react-three-fiber-native.cjs.dev.js +27 -8
- package/native/dist/react-three-fiber-native.cjs.prod.js +27 -8
- package/native/dist/react-three-fiber-native.esm.js +25 -8
- package/package.json +1 -1
|
@@ -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; //
|
|
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
|
|
454
|
+
|
|
455
|
+
if (state.raycaster.camera === undefined) state.raycaster.camera = null;
|
|
456
|
+
} // Intersect object by object
|
|
457
457
|
|
|
458
|
-
|
|
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 (
|
|
461
|
-
|
|
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 (
|
|
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
|
|
469
|
-
let eventObject =
|
|
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({ ...
|
|
483
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
|
|
475
484
|
eventObject
|
|
476
485
|
});
|
|
477
486
|
eventObject = eventObject.parent;
|
|
478
487
|
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
return intersections;
|
|
482
|
-
}
|
|
483
|
-
/** Creates filtered intersects and returns an array of positive hits */
|
|
488
|
+
} // If the interaction is captured, make all capturing targets part of the intersect.
|
|
484
489
|
|
|
485
490
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
internal
|
|
489
|
-
} = store.getState(); // If the interaction is captured, make all capturing targets part of the
|
|
490
|
-
// intersect.
|
|
491
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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') {
|
|
@@ -1150,17 +1147,20 @@ const createStore = (invalidate, advance) => {
|
|
|
1150
1147
|
}
|
|
1151
1148
|
}));
|
|
1152
1149
|
|
|
1150
|
+
const pointer = new THREE.Vector2();
|
|
1153
1151
|
return {
|
|
1152
|
+
set,
|
|
1153
|
+
get,
|
|
1154
1154
|
// Mock objects that have to be configured
|
|
1155
1155
|
gl: null,
|
|
1156
1156
|
camera: null,
|
|
1157
1157
|
raycaster: null,
|
|
1158
1158
|
events: {
|
|
1159
|
+
priority: 1,
|
|
1160
|
+
enabled: true,
|
|
1159
1161
|
connected: false
|
|
1160
1162
|
},
|
|
1161
1163
|
xr: null,
|
|
1162
|
-
set,
|
|
1163
|
-
get,
|
|
1164
1164
|
invalidate: () => invalidate(get()),
|
|
1165
1165
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1166
1166
|
linear: false,
|
|
@@ -1168,7 +1168,8 @@ const createStore = (invalidate, advance) => {
|
|
|
1168
1168
|
scene: prepare(new THREE.Scene()),
|
|
1169
1169
|
controls: null,
|
|
1170
1170
|
clock: new THREE.Clock(),
|
|
1171
|
-
|
|
1171
|
+
pointer,
|
|
1172
|
+
mouse: pointer,
|
|
1172
1173
|
frameloop: 'always',
|
|
1173
1174
|
onPointerMissed: undefined,
|
|
1174
1175
|
performance: {
|
|
@@ -1200,6 +1201,11 @@ const createStore = (invalidate, advance) => {
|
|
|
1200
1201
|
factor: 0,
|
|
1201
1202
|
getCurrentViewport
|
|
1202
1203
|
},
|
|
1204
|
+
setEvents: events => set(state => ({ ...state,
|
|
1205
|
+
events: { ...state.events,
|
|
1206
|
+
events
|
|
1207
|
+
}
|
|
1208
|
+
})),
|
|
1203
1209
|
setSize: (width, height) => {
|
|
1204
1210
|
const camera = get().camera;
|
|
1205
1211
|
const size = {
|
|
@@ -1237,6 +1243,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1237
1243
|
frameloop
|
|
1238
1244
|
}));
|
|
1239
1245
|
},
|
|
1246
|
+
previousRoot: undefined,
|
|
1240
1247
|
internal: {
|
|
1241
1248
|
active: false,
|
|
1242
1249
|
priority: 0,
|
|
@@ -1438,43 +1445,6 @@ function useStore() {
|
|
|
1438
1445
|
function useThree(selector = state => state, equalityFn) {
|
|
1439
1446
|
return useStore()(selector, equalityFn);
|
|
1440
1447
|
}
|
|
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
1448
|
function useFrame(callback, renderPriority = 0) {
|
|
1479
1449
|
const subscribe = useStore().getState().internal.subscribe; // Update ref
|
|
1480
1450
|
|
|
@@ -1501,6 +1471,11 @@ function loadingFn(extensions, onProgress) {
|
|
|
1501
1471
|
};
|
|
1502
1472
|
}
|
|
1503
1473
|
|
|
1474
|
+
function useMemoizedFn(fn) {
|
|
1475
|
+
const fnRef = React.useRef(fn);
|
|
1476
|
+
React.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
|
|
1477
|
+
return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
|
|
1478
|
+
}
|
|
1504
1479
|
function useLoader(Proto, input, extensions, onProgress) {
|
|
1505
1480
|
// Use suspense to load async assets
|
|
1506
1481
|
const keys = Array.isArray(input) ? input : [input];
|
|
@@ -1600,9 +1575,7 @@ function createRoot(canvas) {
|
|
|
1600
1575
|
params,
|
|
1601
1576
|
...options
|
|
1602
1577
|
} = raycastOptions || {};
|
|
1603
|
-
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1604
|
-
enabled: true,
|
|
1605
|
-
...options
|
|
1578
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
|
|
1606
1579
|
});
|
|
1607
1580
|
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1608
1581
|
params: { ...raycaster.params,
|
|
@@ -1717,14 +1690,14 @@ function createRoot(canvas) {
|
|
|
1717
1690
|
return this;
|
|
1718
1691
|
},
|
|
1719
1692
|
|
|
1720
|
-
render(
|
|
1693
|
+
render(children) {
|
|
1721
1694
|
// The root has to be configured before it can be rendered
|
|
1722
1695
|
if (!configured) this.configure();
|
|
1723
1696
|
reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
|
|
1724
1697
|
store: store,
|
|
1725
|
-
|
|
1698
|
+
children: children,
|
|
1726
1699
|
onCreated: onCreated,
|
|
1727
|
-
|
|
1700
|
+
rootElement: canvas
|
|
1728
1701
|
}), fiber, null, () => undefined);
|
|
1729
1702
|
return store;
|
|
1730
1703
|
},
|
|
@@ -1736,35 +1709,36 @@ function createRoot(canvas) {
|
|
|
1736
1709
|
};
|
|
1737
1710
|
}
|
|
1738
1711
|
|
|
1739
|
-
function render(
|
|
1712
|
+
function render(children, canvas, config) {
|
|
1740
1713
|
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1741
1714
|
const root = createRoot(canvas);
|
|
1742
1715
|
root.configure(config);
|
|
1743
|
-
return root.render(
|
|
1716
|
+
return root.render(children);
|
|
1744
1717
|
}
|
|
1745
1718
|
|
|
1746
1719
|
function Provider({
|
|
1747
1720
|
store,
|
|
1748
|
-
|
|
1721
|
+
children,
|
|
1749
1722
|
onCreated,
|
|
1750
|
-
|
|
1723
|
+
rootElement
|
|
1751
1724
|
}) {
|
|
1752
|
-
React.
|
|
1725
|
+
React.useLayoutEffect(() => {
|
|
1753
1726
|
const state = store.getState(); // Flag the canvas active, rendering will now begin
|
|
1754
1727
|
|
|
1755
1728
|
state.set(state => ({
|
|
1756
1729
|
internal: { ...state.internal,
|
|
1757
1730
|
active: true
|
|
1758
1731
|
}
|
|
1759
|
-
})); //
|
|
1732
|
+
})); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1760
1733
|
|
|
1761
|
-
|
|
1734
|
+
if (onCreated) onCreated(state); // Connect events to the targets parent, this is done to ensure events are registered on
|
|
1735
|
+
// a shared target, and not on the canvas itself
|
|
1762
1736
|
|
|
1763
|
-
if (
|
|
1737
|
+
if (!store.getState().events.connected) state.events.connect == null ? void 0 : state.events.connect(rootElement); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1764
1738
|
}, []);
|
|
1765
1739
|
return /*#__PURE__*/React.createElement(context.Provider, {
|
|
1766
1740
|
value: store
|
|
1767
|
-
},
|
|
1741
|
+
}, children);
|
|
1768
1742
|
}
|
|
1769
1743
|
|
|
1770
1744
|
function unmountComponentAtNode(canvas, callback) {
|
|
@@ -1805,20 +1779,58 @@ function createPortal(children, container, state) {
|
|
|
1805
1779
|
}
|
|
1806
1780
|
|
|
1807
1781
|
function Portal({
|
|
1808
|
-
state,
|
|
1782
|
+
state = {},
|
|
1809
1783
|
children,
|
|
1810
1784
|
container
|
|
1811
1785
|
}) {
|
|
1812
1786
|
/** 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
|
|
1787
|
+
* if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
|
|
1814
1788
|
* the "R3F hooks can only be used within the Canvas component!" warning:
|
|
1815
1789
|
* <Canvas>
|
|
1816
1790
|
* {createPortal(...)} */
|
|
1817
|
-
const
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1791
|
+
const {
|
|
1792
|
+
events,
|
|
1793
|
+
...rest
|
|
1794
|
+
} = state;
|
|
1795
|
+
const previousRoot = useStore();
|
|
1796
|
+
const [raycaster] = React.useState(() => new THREE.Raycaster());
|
|
1797
|
+
const inject = React.useCallback((state, injectState) => {
|
|
1798
|
+
const intersect = { ...state
|
|
1799
|
+
};
|
|
1800
|
+
|
|
1801
|
+
if (injectState) {
|
|
1802
|
+
// Only the fields of "state" that do not differ from injectState
|
|
1803
|
+
Object.keys(state).forEach(key => {
|
|
1804
|
+
if ( // Some props should be off-limits
|
|
1805
|
+
!['size', 'viewport', 'internal', 'performance'].includes(key) && // Otherwise filter out the props that are different and let the inject layer take precedence
|
|
1806
|
+
state[key] !== injectState[key]) delete intersect[key];
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
return { ...intersect,
|
|
1811
|
+
scene: container,
|
|
1812
|
+
previousRoot,
|
|
1813
|
+
raycaster,
|
|
1814
|
+
events: { ...state.events,
|
|
1815
|
+
...events
|
|
1816
|
+
},
|
|
1817
|
+
...rest
|
|
1818
|
+
};
|
|
1819
|
+
}, [state]);
|
|
1820
|
+
const [useInjectStore] = React.useState(() => {
|
|
1821
|
+
const store = create((set, get) => ({ ...inject(previousRoot.getState()),
|
|
1822
|
+
set,
|
|
1823
|
+
get
|
|
1824
|
+
}));
|
|
1825
|
+
previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
|
|
1826
|
+
return store;
|
|
1827
|
+
});
|
|
1828
|
+
React.useEffect(() => {
|
|
1829
|
+
useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
|
|
1830
|
+
}, [inject]);
|
|
1831
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, reconciler.createPortal( /*#__PURE__*/React.createElement(context.Provider, {
|
|
1832
|
+
value: useInjectStore
|
|
1833
|
+
}, children), useInjectStore, null));
|
|
1822
1834
|
}
|
|
1823
1835
|
|
|
1824
1836
|
reconciler.injectIntoDevTools({
|
|
@@ -1828,4 +1840,4 @@ reconciler.injectIntoDevTools({
|
|
|
1828
1840
|
});
|
|
1829
1841
|
const act = React.unstable_act;
|
|
1830
1842
|
|
|
1831
|
-
export { createRoot as a,
|
|
1843
|
+
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 };
|