@react-three/fiber 8.0.0-beta-01 → 8.0.0-beta-05
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/dist/declarations/src/core/events.d.ts +5 -4
- package/dist/declarations/src/{web → core}/index.d.ts +6 -8
- package/dist/declarations/src/core/loop.d.ts +2 -1
- package/dist/declarations/src/core/renderer.d.ts +5 -5
- package/dist/declarations/src/core/store.d.ts +15 -7
- package/dist/declarations/src/core/utils.d.ts +8 -1
- package/dist/declarations/src/index.d.ts +4 -2
- package/dist/declarations/src/native/Canvas.d.ts +2 -5
- package/dist/declarations/src/native/events.d.ts +0 -1
- package/dist/declarations/src/native.d.ts +4 -2
- package/dist/declarations/src/three-types.d.ts +12 -24
- package/dist/declarations/src/web/Canvas.d.ts +2 -2
- package/dist/declarations/src/web/events.d.ts +0 -1
- package/dist/{hooks-c89a6f88.esm.js → index-3f4e5f46.esm.js} +459 -163
- package/dist/{hooks-e01f12ec.cjs.prod.js → index-95c17855.cjs.dev.js} +478 -175
- package/dist/{hooks-dd693347.cjs.dev.js → index-ff8b5912.cjs.prod.js} +478 -175
- package/dist/react-three-fiber.cjs.dev.js +83 -300
- package/dist/react-three-fiber.cjs.prod.js +83 -300
- package/dist/react-three-fiber.esm.js +56 -273
- package/native/dist/react-three-fiber-native.cjs.dev.js +160 -392
- package/native/dist/react-three-fiber-native.cjs.prod.js +160 -392
- package/native/dist/react-three-fiber-native.esm.js +135 -367
- package/package.json +21 -13
- package/readme.md +10 -10
- package/dist/declarations/src/native/hooks.d.ts +0 -9
- package/dist/declarations/src/native/index.d.ts +0 -37
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import Reconciler from 'react-reconciler';
|
|
3
|
-
import { DefaultEventPriority, IdleEventPriority } from 'react-reconciler/constants';
|
|
4
1
|
import * as React from 'react';
|
|
5
2
|
import { suspend, preload, clear } from 'suspend-react';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { DefaultEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
|
|
6
5
|
import create from 'zustand';
|
|
6
|
+
import Reconciler from 'react-reconciler';
|
|
7
|
+
import { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
|
|
7
8
|
|
|
8
9
|
var threeTypes = /*#__PURE__*/Object.freeze({
|
|
9
10
|
__proto__: null
|
|
@@ -13,7 +14,34 @@ const DEFAULT = '__default';
|
|
|
13
14
|
const isDiffSet = def => def && !!def.memoized && !!def.changes;
|
|
14
15
|
function calculateDpr(dpr) {
|
|
15
16
|
return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], window.devicePixelRatio), dpr[1]) : dpr;
|
|
16
|
-
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Picks or omits keys from an object
|
|
20
|
+
* `omit` will filter out keys, and otherwise cherry-pick them.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function filterKeys(obj, omit, ...keys) {
|
|
24
|
+
const keysToSelect = new Set(keys);
|
|
25
|
+
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
26
|
+
const shouldInclude = !omit;
|
|
27
|
+
|
|
28
|
+
if (keysToSelect.has(key) === shouldInclude) {
|
|
29
|
+
acc[key] = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return acc;
|
|
33
|
+
}, {});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Clones an object and cherry-picks keys.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const pick = (obj, keys) => filterKeys(obj, false, ...keys);
|
|
40
|
+
/**
|
|
41
|
+
* Clones an object and prunes or omits keys.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
const omit = (obj, keys) => filterKeys(obj, true, ...keys); // A collection of compare functions
|
|
17
45
|
|
|
18
46
|
const is = {
|
|
19
47
|
obj: a => a === Object(a) && !is.arr(a) && typeof a !== 'function',
|
|
@@ -62,8 +90,7 @@ function dispose(obj) {
|
|
|
62
90
|
if (obj.dispose && obj.type !== 'Scene') obj.dispose();
|
|
63
91
|
|
|
64
92
|
for (const p in obj) {
|
|
65
|
-
|
|
66
|
-
(_dispose = (_ref = p).dispose) == null ? void 0 : _dispose.call(_ref);
|
|
93
|
+
p.dispose == null ? void 0 : p.dispose();
|
|
67
94
|
delete obj[p];
|
|
68
95
|
}
|
|
69
96
|
} // Each object in the scene carries a small LocalState descriptor
|
|
@@ -84,6 +111,49 @@ function prepare(object, state) {
|
|
|
84
111
|
}
|
|
85
112
|
|
|
86
113
|
return object;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function resolve(instance, key) {
|
|
117
|
+
let target = instance;
|
|
118
|
+
|
|
119
|
+
if (key.includes('-')) {
|
|
120
|
+
const entries = key.split('-');
|
|
121
|
+
const last = entries.pop();
|
|
122
|
+
target = entries.reduce((acc, key) => acc[key], instance);
|
|
123
|
+
return {
|
|
124
|
+
target,
|
|
125
|
+
key: last
|
|
126
|
+
};
|
|
127
|
+
} else return {
|
|
128
|
+
target,
|
|
129
|
+
key
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function attach(parent, child, type) {
|
|
134
|
+
if (is.str(type)) {
|
|
135
|
+
const {
|
|
136
|
+
target,
|
|
137
|
+
key
|
|
138
|
+
} = resolve(parent, type);
|
|
139
|
+
parent.__r3f.previousAttach = target[key];
|
|
140
|
+
target[key] = child;
|
|
141
|
+
} else if (is.arr(type)) {
|
|
142
|
+
const [attach] = type;
|
|
143
|
+
if (is.str(attach)) parent[attach](child);else if (is.fun(attach)) attach(parent, child);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function detach(parent, child, type) {
|
|
147
|
+
if (is.str(type)) {
|
|
148
|
+
const {
|
|
149
|
+
target,
|
|
150
|
+
key
|
|
151
|
+
} = resolve(parent, type);
|
|
152
|
+
target[key] = parent.__r3f.previousAttach;
|
|
153
|
+
} else if (is.arr(type)) {
|
|
154
|
+
const [, detach] = type;
|
|
155
|
+
if (is.str(detach)) parent[detach](child);else if (is.fun(detach)) detach(parent, child);
|
|
156
|
+
}
|
|
87
157
|
} // Shallow check arrays, but check objects atomically
|
|
88
158
|
|
|
89
159
|
function checkShallow(a, b) {
|
|
@@ -113,7 +183,9 @@ function diffProps(instance, {
|
|
|
113
183
|
if (remove) {
|
|
114
184
|
const previousKeys = Object.keys(previous);
|
|
115
185
|
|
|
116
|
-
for (let i = 0; i < previousKeys.length; i++)
|
|
186
|
+
for (let i = 0; i < previousKeys.length; i++) {
|
|
187
|
+
if (!props.hasOwnProperty(previousKeys[i])) entries.unshift([previousKeys[i], DEFAULT + 'remove']);
|
|
188
|
+
}
|
|
117
189
|
}
|
|
118
190
|
|
|
119
191
|
entries.forEach(([key, value]) => {
|
|
@@ -140,7 +212,7 @@ function diffProps(instance, {
|
|
|
140
212
|
};
|
|
141
213
|
} // This function applies a set of changes to the instance
|
|
142
214
|
|
|
143
|
-
function applyProps(instance, data) {
|
|
215
|
+
function applyProps$1(instance, data) {
|
|
144
216
|
var _instance$__r3f3, _root$getState;
|
|
145
217
|
|
|
146
218
|
// Filter equals, events and reserved props
|
|
@@ -184,7 +256,9 @@ function applyProps(instance, data) {
|
|
|
184
256
|
value = defaultClassCall[targetProp]; // destory the instance
|
|
185
257
|
|
|
186
258
|
if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
|
|
187
|
-
} else
|
|
259
|
+
} else {
|
|
260
|
+
value = 0;
|
|
261
|
+
}
|
|
188
262
|
} // Deal with pointer events ...
|
|
189
263
|
|
|
190
264
|
|
|
@@ -193,35 +267,39 @@ function applyProps(instance, data) {
|
|
|
193
267
|
localState.eventCount = Object.keys(localState.handlers).length;
|
|
194
268
|
} // Special treatment for objects with support for set/copy, and layers
|
|
195
269
|
else if (targetProp && targetProp.set && (targetProp.copy || targetProp instanceof THREE.Layers)) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
270
|
+
// If value is an array
|
|
271
|
+
if (Array.isArray(value)) {
|
|
272
|
+
if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
|
|
273
|
+
} // Test again target.copy(class) next ...
|
|
274
|
+
else if (targetProp.copy && value && value.constructor && targetProp.constructor.name === value.constructor.name) {
|
|
275
|
+
targetProp.copy(value);
|
|
276
|
+
} // If nothing else fits, just set the single value, ignore undefined
|
|
277
|
+
// https://github.com/pmndrs/react-three-fiber/issues/274
|
|
278
|
+
else if (value !== undefined) {
|
|
279
|
+
const isColor = targetProp instanceof THREE.Color; // Allow setting array scalars
|
|
280
|
+
|
|
281
|
+
if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
|
|
282
|
+
else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
|
|
283
|
+
else targetProp.set(value); // Auto-convert sRGB colors, for now ...
|
|
284
|
+
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
285
|
+
|
|
286
|
+
if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
|
|
287
|
+
} // Else, just overwrite the value
|
|
212
288
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
289
|
+
} else {
|
|
290
|
+
currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
|
|
291
|
+
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
216
292
|
|
|
217
|
-
|
|
218
|
-
|
|
293
|
+
if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) {
|
|
294
|
+
currentInstance[key].encoding = THREE.sRGBEncoding;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
219
297
|
|
|
220
298
|
invalidateInstance(instance);
|
|
221
299
|
return instance;
|
|
222
300
|
});
|
|
223
301
|
|
|
224
|
-
if (rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
|
|
302
|
+
if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
|
|
225
303
|
// Pre-emptively remove the instance from the interaction manager
|
|
226
304
|
const index = rootState.internal.interaction.indexOf(instance);
|
|
227
305
|
if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
|
|
@@ -244,12 +322,41 @@ function updateInstance(instance) {
|
|
|
244
322
|
|
|
245
323
|
function makeId(event) {
|
|
246
324
|
return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
|
|
325
|
+
} // https://github.com/facebook/react/tree/main/packages/react-reconciler#getcurrenteventpriority
|
|
326
|
+
// Gives React a clue as to how import the current interaction is
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
function getEventPriority() {
|
|
330
|
+
var _window, _window$event;
|
|
331
|
+
|
|
332
|
+
let name = (_window = window) == null ? void 0 : (_window$event = _window.event) == null ? void 0 : _window$event.type;
|
|
333
|
+
|
|
334
|
+
switch (name) {
|
|
335
|
+
case 'click':
|
|
336
|
+
case 'contextmenu':
|
|
337
|
+
case 'dblclick':
|
|
338
|
+
case 'pointercancel':
|
|
339
|
+
case 'pointerdown':
|
|
340
|
+
case 'pointerup':
|
|
341
|
+
return DiscreteEventPriority;
|
|
342
|
+
|
|
343
|
+
case 'pointermove':
|
|
344
|
+
case 'pointerout':
|
|
345
|
+
case 'pointerover':
|
|
346
|
+
case 'pointerenter':
|
|
347
|
+
case 'pointerleave':
|
|
348
|
+
case 'wheel':
|
|
349
|
+
return ContinuousEventPriority;
|
|
350
|
+
|
|
351
|
+
default:
|
|
352
|
+
return DefaultEventPriority;
|
|
353
|
+
}
|
|
247
354
|
}
|
|
248
|
-
/**
|
|
355
|
+
/**
|
|
356
|
+
* Release pointer captures.
|
|
249
357
|
* This is called by releasePointerCapture in the API, and when an object is removed.
|
|
250
358
|
*/
|
|
251
359
|
|
|
252
|
-
|
|
253
360
|
function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
254
361
|
const captureData = captures.get(obj);
|
|
255
362
|
|
|
@@ -284,7 +391,7 @@ function createEvents(store) {
|
|
|
284
391
|
/** Sets up defaultRaycaster */
|
|
285
392
|
|
|
286
393
|
function prepareRay(event) {
|
|
287
|
-
var
|
|
394
|
+
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
288
395
|
|
|
289
396
|
const state = store.getState();
|
|
290
397
|
const {
|
|
@@ -295,14 +402,11 @@ function createEvents(store) {
|
|
|
295
402
|
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
296
403
|
// Events trigger outside of canvas when moved
|
|
297
404
|
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const
|
|
303
|
-
width,
|
|
304
|
-
height
|
|
305
|
-
} = size;
|
|
405
|
+
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
406
|
+
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
407
|
+
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
408
|
+
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
409
|
+
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
306
410
|
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
307
411
|
raycaster.setFromCamera(mouse, camera);
|
|
308
412
|
}
|
|
@@ -532,13 +636,16 @@ function createEvents(store) {
|
|
|
532
636
|
|
|
533
637
|
case 'onLostPointerCapture':
|
|
534
638
|
return event => {
|
|
535
|
-
|
|
639
|
+
const {
|
|
640
|
+
internal
|
|
641
|
+
} = store.getState();
|
|
642
|
+
|
|
643
|
+
if ('pointerId' in event && !internal.capturedMap.has(event.pointerId)) {
|
|
536
644
|
// If the object event interface had onLostPointerCapture, we'd call it here on every
|
|
537
645
|
// object that's getting removed.
|
|
538
|
-
|
|
646
|
+
internal.capturedMap.delete(event.pointerId);
|
|
647
|
+
cancelPointer([]);
|
|
539
648
|
}
|
|
540
|
-
|
|
541
|
-
cancelPointer([]);
|
|
542
649
|
};
|
|
543
650
|
} // Any other pointer goes here ...
|
|
544
651
|
|
|
@@ -548,7 +655,8 @@ function createEvents(store) {
|
|
|
548
655
|
onPointerMissed,
|
|
549
656
|
internal
|
|
550
657
|
} = store.getState();
|
|
551
|
-
prepareRay(event);
|
|
658
|
+
prepareRay(event);
|
|
659
|
+
internal.lastEvent.current = event; // Get fresh intersects
|
|
552
660
|
|
|
553
661
|
const isPointerMove = name === 'onPointerMove';
|
|
554
662
|
const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
|
|
@@ -606,12 +714,17 @@ function createEvents(store) {
|
|
|
606
714
|
if (handler) {
|
|
607
715
|
// Forward all events back to their respective handlers with the exception of click events,
|
|
608
716
|
// which must use the initial target
|
|
609
|
-
if (
|
|
717
|
+
if (!isClickEvent || internal.initialHits.includes(eventObject)) {
|
|
610
718
|
// Missed events have to come first
|
|
611
719
|
pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object))); // Now call the handler
|
|
612
720
|
|
|
613
721
|
handler(data);
|
|
614
722
|
}
|
|
723
|
+
} else {
|
|
724
|
+
// Trigger onPointerMissed on all elements that have pointer over/out handlers, but not click and weren't hit
|
|
725
|
+
if (isClickEvent && internal.initialHits.includes(eventObject)) {
|
|
726
|
+
pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object)));
|
|
727
|
+
}
|
|
615
728
|
}
|
|
616
729
|
}
|
|
617
730
|
});
|
|
@@ -657,6 +770,7 @@ let extend = objects => void (catalogue = { ...catalogue,
|
|
|
657
770
|
function createRenderer(roots, getEventPriority) {
|
|
658
771
|
function createInstance(type, {
|
|
659
772
|
args = [],
|
|
773
|
+
attach,
|
|
660
774
|
...props
|
|
661
775
|
}, root, hostContext, internalInstanceHandle) {
|
|
662
776
|
let name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
@@ -673,87 +787,65 @@ function createRenderer(roots, getEventPriority) {
|
|
|
673
787
|
} // Assert that by now we have a valid root
|
|
674
788
|
|
|
675
789
|
|
|
676
|
-
if (!root || !isStore(root)) throw `No valid root for ${name}!`;
|
|
790
|
+
if (!root || !isStore(root)) throw `No valid root for ${name}!`; // Auto-attach geometries and materials
|
|
791
|
+
|
|
792
|
+
if (attach === undefined) {
|
|
793
|
+
if (name.endsWith('Geometry')) attach = 'geometry';else if (name.endsWith('Material')) attach = 'material';
|
|
794
|
+
}
|
|
677
795
|
|
|
678
796
|
if (type === 'primitive') {
|
|
679
797
|
if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
|
|
680
798
|
const object = props.object;
|
|
681
799
|
instance = prepare(object, {
|
|
682
800
|
root,
|
|
801
|
+
attach,
|
|
683
802
|
primitive: true
|
|
684
803
|
});
|
|
685
804
|
} else {
|
|
686
|
-
const target = catalogue[name]
|
|
687
|
-
|
|
805
|
+
const target = catalogue[name];
|
|
806
|
+
|
|
807
|
+
if (!target) {
|
|
808
|
+
throw `${name} is not part of the THREE namespace! Did you forget to extend? See: https://github.com/pmndrs/react-three-fiber/blob/master/markdown/api.md#using-3rd-party-objects-declaratively`;
|
|
809
|
+
} // Throw if an object or literal was passed for args
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
|
|
688
813
|
// Append memoized props with args so it's not forgotten
|
|
689
814
|
|
|
690
815
|
instance = prepare(new target(...args), {
|
|
691
816
|
root,
|
|
817
|
+
attach,
|
|
818
|
+
// TODO: Figure out what this is for
|
|
692
819
|
memoizedProps: {
|
|
693
820
|
args: args.length === 0 ? null : args
|
|
694
821
|
}
|
|
695
822
|
});
|
|
696
|
-
} // Auto-attach geometries and materials
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (!('attachFns' in props)) {
|
|
700
|
-
if (name.endsWith('Geometry')) {
|
|
701
|
-
props = {
|
|
702
|
-
attach: 'geometry',
|
|
703
|
-
...props
|
|
704
|
-
};
|
|
705
|
-
} else if (name.endsWith('Material')) {
|
|
706
|
-
props = {
|
|
707
|
-
attach: 'material',
|
|
708
|
-
...props
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
823
|
} // It should NOT call onUpdate on object instanciation, because it hasn't been added to the
|
|
712
824
|
// view yet. If the callback relies on references for instance, they won't be ready yet, this is
|
|
713
825
|
// why it passes "true" here
|
|
714
826
|
|
|
715
827
|
|
|
716
|
-
applyProps(instance, props);
|
|
828
|
+
applyProps$1(instance, props);
|
|
717
829
|
return instance;
|
|
718
830
|
}
|
|
719
831
|
|
|
720
832
|
function appendChild(parentInstance, child) {
|
|
721
|
-
let
|
|
833
|
+
let added = false;
|
|
722
834
|
|
|
723
835
|
if (child) {
|
|
724
836
|
// The attach attribute implies that the object attaches itself on the parent
|
|
725
|
-
if (child.
|
|
726
|
-
|
|
727
|
-
parentInstance[child.attachArray].push(child);
|
|
728
|
-
} else if (child.attachObject) {
|
|
729
|
-
if (!is.obj(parentInstance[child.attachObject[0]])) parentInstance[child.attachObject[0]] = {};
|
|
730
|
-
parentInstance[child.attachObject[0]][child.attachObject[1]] = child;
|
|
731
|
-
} else if (child.attach && !is.fun(child.attach)) {
|
|
732
|
-
parentInstance[child.attach] = child;
|
|
733
|
-
} else if (is.arr(child.attachFns)) {
|
|
734
|
-
const [attachFn] = child.attachFns;
|
|
735
|
-
|
|
736
|
-
if (is.str(attachFn) && is.fun(parentInstance[attachFn])) {
|
|
737
|
-
parentInstance[attachFn](child);
|
|
738
|
-
} else if (is.fun(attachFn)) {
|
|
739
|
-
attachFn(child, parentInstance);
|
|
740
|
-
}
|
|
837
|
+
if (child.__r3f.attach) {
|
|
838
|
+
attach(parentInstance, child, child.__r3f.attach);
|
|
741
839
|
} else if (child.isObject3D && parentInstance.isObject3D) {
|
|
742
840
|
// add in the usual parent-child way
|
|
743
841
|
parentInstance.add(child);
|
|
744
|
-
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
if (!addedAsChild) {
|
|
748
|
-
// This is for anything that used attach, and for non-Object3Ds that don't get attached to props;
|
|
749
|
-
// that is, anything that's a child in React but not a child in the scenegraph.
|
|
750
|
-
parentInstance.__r3f.objects.push(child);
|
|
751
|
-
}
|
|
842
|
+
added = true;
|
|
843
|
+
} // This is for anything that used attach, and for non-Object3Ds that don't get attached to props;
|
|
844
|
+
// that is, anything that's a child in React but not a child in the scenegraph.
|
|
752
845
|
|
|
753
|
-
if (!child.__r3f) {
|
|
754
|
-
prepare(child, {});
|
|
755
|
-
}
|
|
756
846
|
|
|
847
|
+
if (!added) parentInstance.__r3f.objects.push(child);
|
|
848
|
+
if (!child.__r3f) prepare(child, {});
|
|
757
849
|
child.__r3f.parent = parentInstance;
|
|
758
850
|
updateInstance(child);
|
|
759
851
|
invalidateInstance(child);
|
|
@@ -764,13 +856,8 @@ function createRenderer(roots, getEventPriority) {
|
|
|
764
856
|
let added = false;
|
|
765
857
|
|
|
766
858
|
if (child) {
|
|
767
|
-
if (child.
|
|
768
|
-
|
|
769
|
-
if (!is.arr(array)) parentInstance[child.attachArray] = [];
|
|
770
|
-
array.splice(array.indexOf(beforeChild), 0, child);
|
|
771
|
-
} else if (child.attachObject || child.attach && !is.fun(child.attach)) {
|
|
772
|
-
// attach and attachObject don't have an order anyway, so just append
|
|
773
|
-
return appendChild(parentInstance, child);
|
|
859
|
+
if (child.__r3f.attach) {
|
|
860
|
+
attach(parentInstance, child, child.__r3f.attach);
|
|
774
861
|
} else if (child.isObject3D && parentInstance.isObject3D) {
|
|
775
862
|
child.parent = parentInstance;
|
|
776
863
|
child.dispatchEvent({
|
|
@@ -782,14 +869,8 @@ function createRenderer(roots, getEventPriority) {
|
|
|
782
869
|
added = true;
|
|
783
870
|
}
|
|
784
871
|
|
|
785
|
-
if (!added)
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
if (!child.__r3f) {
|
|
790
|
-
prepare(child, {});
|
|
791
|
-
}
|
|
792
|
-
|
|
872
|
+
if (!added) parentInstance.__r3f.objects.push(child);
|
|
873
|
+
if (!child.__r3f) prepare(child, {});
|
|
793
874
|
child.__r3f.parent = parentInstance;
|
|
794
875
|
updateInstance(child);
|
|
795
876
|
invalidateInstance(child);
|
|
@@ -804,29 +885,13 @@ function createRenderer(roots, getEventPriority) {
|
|
|
804
885
|
if (child) {
|
|
805
886
|
var _parentInstance$__r3f, _child$__r3f2;
|
|
806
887
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
if ((_parentInstance$__r3f = parentInstance.__r3f) != null && _parentInstance$__r3f.objects) {
|
|
812
|
-
parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child);
|
|
813
|
-
} // Remove attachment
|
|
888
|
+
// Clear the parent reference
|
|
889
|
+
if (child.__r3f) child.__r3f.parent = null; // Remove child from the parents objects
|
|
814
890
|
|
|
891
|
+
if ((_parentInstance$__r3f = parentInstance.__r3f) != null && _parentInstance$__r3f.objects) parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child); // Remove attachment
|
|
815
892
|
|
|
816
|
-
if (child.
|
|
817
|
-
parentInstance
|
|
818
|
-
} else if (child.attachObject) {
|
|
819
|
-
delete parentInstance[child.attachObject[0]][child.attachObject[1]];
|
|
820
|
-
} else if (child.attach && !is.fun(child.attach)) {
|
|
821
|
-
parentInstance[child.attach] = null;
|
|
822
|
-
} else if (is.arr(child.attachFns)) {
|
|
823
|
-
const [, detachFn] = child.attachFns;
|
|
824
|
-
|
|
825
|
-
if (is.str(detachFn) && is.fun(parentInstance[detachFn])) {
|
|
826
|
-
parentInstance[detachFn](child);
|
|
827
|
-
} else if (is.fun(detachFn)) {
|
|
828
|
-
detachFn(child, parentInstance);
|
|
829
|
-
}
|
|
893
|
+
if (child.__r3f.attach) {
|
|
894
|
+
detach(parentInstance, child, child.__r3f.attach);
|
|
830
895
|
} else if (child.isObject3D && parentInstance.isObject3D) {
|
|
831
896
|
var _child$__r3f;
|
|
832
897
|
|
|
@@ -868,7 +933,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
868
933
|
|
|
869
934
|
|
|
870
935
|
if (shouldDispose && child.dispose && child.type !== 'Scene') {
|
|
871
|
-
|
|
936
|
+
unstable_scheduleCallback(unstable_IdlePriority, () => {
|
|
872
937
|
try {
|
|
873
938
|
child.dispose();
|
|
874
939
|
} catch (e) {
|
|
@@ -900,10 +965,13 @@ function createRenderer(roots, getEventPriority) {
|
|
|
900
965
|
|
|
901
966
|
instance.__r3f.objects = [];
|
|
902
967
|
removeChild(parent, instance);
|
|
903
|
-
appendChild(parent, newInstance) //
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
968
|
+
appendChild(parent, newInstance); // Re-bind event handlers
|
|
969
|
+
|
|
970
|
+
if (newInstance.raycast && newInstance.__r3f.eventCount) {
|
|
971
|
+
const rootState = newInstance.__r3f.root.getState();
|
|
972
|
+
|
|
973
|
+
rootState.internal.interaction.push(newInstance);
|
|
974
|
+
} // This evil hack switches the react-internal fiber node
|
|
907
975
|
[fiber, fiber.alternate].forEach(fiber => {
|
|
908
976
|
if (fiber !== null) {
|
|
909
977
|
fiber.stateNode = newInstance;
|
|
@@ -929,7 +997,9 @@ function createRenderer(roots, getEventPriority) {
|
|
|
929
997
|
insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
|
|
930
998
|
|
|
931
999
|
prepareUpdate(instance, type, oldProps, newProps) {
|
|
932
|
-
if (instance.__r3f.primitive && newProps.object && newProps.object !== instance)
|
|
1000
|
+
if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) {
|
|
1001
|
+
return [true];
|
|
1002
|
+
} else {
|
|
933
1003
|
// This is a data object, let's extract critical information about it
|
|
934
1004
|
const {
|
|
935
1005
|
args: argsNew = [],
|
|
@@ -940,7 +1010,9 @@ function createRenderer(roots, getEventPriority) {
|
|
|
940
1010
|
args: argsOld = [],
|
|
941
1011
|
children: cO,
|
|
942
1012
|
...restOld
|
|
943
|
-
} = oldProps; //
|
|
1013
|
+
} = oldProps; // Throw if an object or literal was passed for args
|
|
1014
|
+
|
|
1015
|
+
if (!Array.isArray(argsNew)) throw 'The args prop must be an array!'; // If it has new props or arguments, then it needs to be re-instanciated
|
|
944
1016
|
|
|
945
1017
|
if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
|
|
946
1018
|
|
|
@@ -954,21 +1026,33 @@ function createRenderer(roots, getEventPriority) {
|
|
|
954
1026
|
commitUpdate(instance, [reconstruct, diff], type, oldProps, newProps, fiber) {
|
|
955
1027
|
// Reconstruct when args or <primitive object={...} have changes
|
|
956
1028
|
if (reconstruct) switchInstance(instance, type, newProps, fiber); // Otherwise just overwrite props
|
|
957
|
-
else applyProps(instance, diff);
|
|
1029
|
+
else applyProps$1(instance, diff);
|
|
958
1030
|
},
|
|
959
1031
|
|
|
960
1032
|
hideInstance(instance) {
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1033
|
+
var _instance$__r3f2;
|
|
1034
|
+
|
|
1035
|
+
// Deatch while the instance is hidden
|
|
1036
|
+
const {
|
|
1037
|
+
attach: type,
|
|
1038
|
+
parent
|
|
1039
|
+
} = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {};
|
|
1040
|
+
if (type && parent) detach(parent, instance, type);
|
|
1041
|
+
if (instance.isObject3D) instance.visible = false;
|
|
1042
|
+
invalidateInstance(instance);
|
|
965
1043
|
},
|
|
966
1044
|
|
|
967
1045
|
unhideInstance(instance, props) {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1046
|
+
var _instance$__r3f3;
|
|
1047
|
+
|
|
1048
|
+
// Re-attach when the instance is unhidden
|
|
1049
|
+
const {
|
|
1050
|
+
attach: type,
|
|
1051
|
+
parent
|
|
1052
|
+
} = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {};
|
|
1053
|
+
if (type && parent) attach(parent, instance, type);
|
|
1054
|
+
if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
|
|
1055
|
+
invalidateInstance(instance);
|
|
972
1056
|
},
|
|
973
1057
|
|
|
974
1058
|
createInstance,
|
|
@@ -981,7 +1065,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
981
1065
|
isPrimaryRenderer: false,
|
|
982
1066
|
getCurrentEventPriority: () => getEventPriority ? getEventPriority() : DefaultEventPriority,
|
|
983
1067
|
// @ts-ignore
|
|
984
|
-
now: is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
1068
|
+
now: typeof performance !== 'undefined' && is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
985
1069
|
// @ts-ignore
|
|
986
1070
|
scheduleTimeout: is.fun(setTimeout) ? setTimeout : undefined,
|
|
987
1071
|
// @ts-ignore
|
|
@@ -997,8 +1081,30 @@ function createRenderer(roots, getEventPriority) {
|
|
|
997
1081
|
getRootHostContext: () => null,
|
|
998
1082
|
getChildHostContext: parentHostContext => parentHostContext,
|
|
999
1083
|
createTextInstance: () => {},
|
|
1000
|
-
|
|
1001
|
-
|
|
1084
|
+
|
|
1085
|
+
finalizeInitialChildren(instance) {
|
|
1086
|
+
var _instance$__r3f4;
|
|
1087
|
+
|
|
1088
|
+
// https://github.com/facebook/react/issues/20271
|
|
1089
|
+
// Returning true will trigger commitMount
|
|
1090
|
+
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1091
|
+
return !!localState.handlers;
|
|
1092
|
+
},
|
|
1093
|
+
|
|
1094
|
+
commitMount(instance)
|
|
1095
|
+
/*, type, props*/
|
|
1096
|
+
{
|
|
1097
|
+
var _instance$__r3f5;
|
|
1098
|
+
|
|
1099
|
+
// https://github.com/facebook/react/issues/20271
|
|
1100
|
+
// This will make sure events are only added once to the central container
|
|
1101
|
+
const localState = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1102
|
+
|
|
1103
|
+
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1104
|
+
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
1105
|
+
}
|
|
1106
|
+
},
|
|
1107
|
+
|
|
1002
1108
|
shouldDeprioritizeSubtree: () => false,
|
|
1003
1109
|
prepareForCommit: () => null,
|
|
1004
1110
|
preparePortalMount: containerInfo => prepare(containerInfo),
|
|
@@ -1009,7 +1115,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1009
1115
|
});
|
|
1010
1116
|
return {
|
|
1011
1117
|
reconciler,
|
|
1012
|
-
applyProps
|
|
1118
|
+
applyProps: applyProps$1
|
|
1013
1119
|
};
|
|
1014
1120
|
}
|
|
1015
1121
|
|
|
@@ -1120,18 +1226,19 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1120
1226
|
})); // Handle frame behavior in WebXR
|
|
1121
1227
|
|
|
1122
1228
|
|
|
1123
|
-
const handleXRFrame = timestamp => {
|
|
1229
|
+
const handleXRFrame = (timestamp, frame) => {
|
|
1124
1230
|
const state = get();
|
|
1125
1231
|
if (state.frameloop === 'never') return;
|
|
1126
|
-
advance(timestamp, true);
|
|
1232
|
+
advance(timestamp, true, state, frame);
|
|
1127
1233
|
}; // Toggle render switching on session
|
|
1128
1234
|
|
|
1129
1235
|
|
|
1130
1236
|
const handleSessionChange = () => {
|
|
1131
|
-
gl.xr.enabled = gl.xr.isPresenting;
|
|
1132
|
-
|
|
1237
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-expect-error
|
|
1238
|
+
// WebXRManager's signature is incorrect.
|
|
1239
|
+
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1133
1240
|
|
|
1134
|
-
|
|
1241
|
+
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1135
1242
|
}; // WebXR session manager
|
|
1136
1243
|
|
|
1137
1244
|
|
|
@@ -1212,6 +1319,9 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1212
1319
|
dpr: calculateDpr(dpr)
|
|
1213
1320
|
}
|
|
1214
1321
|
})),
|
|
1322
|
+
setFrameloop: (frameloop = 'always') => set(() => ({
|
|
1323
|
+
frameloop
|
|
1324
|
+
})),
|
|
1215
1325
|
events: {
|
|
1216
1326
|
connected: false
|
|
1217
1327
|
},
|
|
@@ -1220,6 +1330,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1220
1330
|
priority: 0,
|
|
1221
1331
|
frames: 0,
|
|
1222
1332
|
lastProps: props,
|
|
1333
|
+
lastEvent: /*#__PURE__*/React.createRef(),
|
|
1223
1334
|
interaction: [],
|
|
1224
1335
|
hovered: new Map(),
|
|
1225
1336
|
subscribers: [],
|
|
@@ -1276,7 +1387,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1276
1387
|
if (size !== oldSize || viewport.dpr !== oldDpr) {
|
|
1277
1388
|
// https://github.com/pmndrs/react-three-fiber/issues/92
|
|
1278
1389
|
// Do not mess with the camera if it belongs to the user
|
|
1279
|
-
if (!(internal.lastProps.camera instanceof THREE.Camera)) {
|
|
1390
|
+
if (!camera.manual && !(internal.lastProps.camera instanceof THREE.Camera)) {
|
|
1280
1391
|
if (isOrthographicCamera(camera)) {
|
|
1281
1392
|
camera.left = size.width / -2;
|
|
1282
1393
|
camera.right = size.width / 2;
|
|
@@ -1325,7 +1436,7 @@ function run(effects, timestamp) {
|
|
|
1325
1436
|
for (i = 0; i < effects.length; i++) effects[i](timestamp);
|
|
1326
1437
|
}
|
|
1327
1438
|
|
|
1328
|
-
function render(timestamp, state) {
|
|
1439
|
+
function render$1(timestamp, state, frame) {
|
|
1329
1440
|
// Run local effects
|
|
1330
1441
|
let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
|
|
1331
1442
|
|
|
@@ -1336,7 +1447,7 @@ function render(timestamp, state) {
|
|
|
1336
1447
|
} // Call subscribers (useFrame)
|
|
1337
1448
|
|
|
1338
1449
|
|
|
1339
|
-
for (i = 0; i < state.internal.subscribers.length; i++) state.internal.subscribers[i].ref.current(state, delta); // Render content
|
|
1450
|
+
for (i = 0; i < state.internal.subscribers.length; i++) state.internal.subscribers[i].ref.current(state, delta, frame); // Render content
|
|
1340
1451
|
|
|
1341
1452
|
|
|
1342
1453
|
if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
|
|
@@ -1360,7 +1471,9 @@ function createLoop(roots) {
|
|
|
1360
1471
|
|
|
1361
1472
|
const state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
|
|
1362
1473
|
|
|
1363
|
-
if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting))
|
|
1474
|
+
if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting)) {
|
|
1475
|
+
repeat += render$1(timestamp, state);
|
|
1476
|
+
}
|
|
1364
1477
|
}); // Run after-effects
|
|
1365
1478
|
|
|
1366
1479
|
run(globalAfterEffects, timestamp); // Keep on looping if anything invalidates the frameloop
|
|
@@ -1385,9 +1498,9 @@ function createLoop(roots) {
|
|
|
1385
1498
|
}
|
|
1386
1499
|
}
|
|
1387
1500
|
|
|
1388
|
-
function advance(timestamp, runGlobalEffects = true, state) {
|
|
1501
|
+
function advance(timestamp, runGlobalEffects = true, state, frame) {
|
|
1389
1502
|
if (runGlobalEffects) run(globalEffects, timestamp);
|
|
1390
|
-
if (!state) roots.forEach(root => render(timestamp, root.store.getState()));else render(timestamp, state);
|
|
1503
|
+
if (!state) roots.forEach(root => render$1(timestamp, root.store.getState()));else render$1(timestamp, state, frame);
|
|
1391
1504
|
if (runGlobalEffects) run(globalAfterEffects, timestamp);
|
|
1392
1505
|
}
|
|
1393
1506
|
|
|
@@ -1452,4 +1565,187 @@ useLoader.clear = function (Proto, input) {
|
|
|
1452
1565
|
return clear([Proto, ...keys]);
|
|
1453
1566
|
};
|
|
1454
1567
|
|
|
1455
|
-
|
|
1568
|
+
const roots = new Map();
|
|
1569
|
+
const {
|
|
1570
|
+
invalidate,
|
|
1571
|
+
advance
|
|
1572
|
+
} = createLoop(roots);
|
|
1573
|
+
const {
|
|
1574
|
+
reconciler,
|
|
1575
|
+
applyProps
|
|
1576
|
+
} = createRenderer(roots, getEventPriority);
|
|
1577
|
+
|
|
1578
|
+
const createRendererInstance = (gl, canvas) => {
|
|
1579
|
+
const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
|
|
1580
|
+
if (isRenderer(customRenderer)) return customRenderer;
|
|
1581
|
+
const renderer = new THREE.WebGLRenderer({
|
|
1582
|
+
powerPreference: 'high-performance',
|
|
1583
|
+
canvas: canvas,
|
|
1584
|
+
antialias: true,
|
|
1585
|
+
alpha: true,
|
|
1586
|
+
...gl
|
|
1587
|
+
}); // Set color management
|
|
1588
|
+
|
|
1589
|
+
renderer.outputEncoding = THREE.sRGBEncoding;
|
|
1590
|
+
renderer.toneMapping = THREE.ACESFilmicToneMapping; // Set gl props
|
|
1591
|
+
|
|
1592
|
+
if (gl) applyProps(renderer, gl);
|
|
1593
|
+
return renderer;
|
|
1594
|
+
};
|
|
1595
|
+
|
|
1596
|
+
function createRoot(canvas, config) {
|
|
1597
|
+
return {
|
|
1598
|
+
render: element => {
|
|
1599
|
+
var _store;
|
|
1600
|
+
|
|
1601
|
+
let {
|
|
1602
|
+
gl,
|
|
1603
|
+
size,
|
|
1604
|
+
events,
|
|
1605
|
+
onCreated,
|
|
1606
|
+
...props
|
|
1607
|
+
} = config || {}; // Allow size to take on container bounds initially
|
|
1608
|
+
|
|
1609
|
+
if (!size) {
|
|
1610
|
+
var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
|
|
1611
|
+
|
|
1612
|
+
size = {
|
|
1613
|
+
width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
|
|
1614
|
+
height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
let root = roots.get(canvas);
|
|
1619
|
+
let fiber = root == null ? void 0 : root.fiber;
|
|
1620
|
+
let store = root == null ? void 0 : root.store;
|
|
1621
|
+
let state = (_store = store) == null ? void 0 : _store.getState();
|
|
1622
|
+
|
|
1623
|
+
if (fiber && state) {
|
|
1624
|
+
// When a root was found, see if any fundamental props must be changed or exchanged
|
|
1625
|
+
// Check pixelratio
|
|
1626
|
+
if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
|
|
1627
|
+
|
|
1628
|
+
if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // Check frameloop
|
|
1629
|
+
|
|
1630
|
+
if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
|
|
1631
|
+
// Changes to the color-space
|
|
1632
|
+
|
|
1633
|
+
const linearChanged = props.linear !== state.internal.lastProps.linear;
|
|
1634
|
+
|
|
1635
|
+
if (linearChanged) {
|
|
1636
|
+
unmountComponentAtNode(canvas);
|
|
1637
|
+
fiber = undefined;
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
if (!fiber) {
|
|
1642
|
+
// If no root has been found, make one
|
|
1643
|
+
// Create gl
|
|
1644
|
+
const glRenderer = createRendererInstance(gl, canvas); // Create store
|
|
1645
|
+
|
|
1646
|
+
store = createStore(applyProps, invalidate, advance, {
|
|
1647
|
+
gl: glRenderer,
|
|
1648
|
+
size,
|
|
1649
|
+
...props
|
|
1650
|
+
});
|
|
1651
|
+
const state = store.getState(); // Create renderer
|
|
1652
|
+
|
|
1653
|
+
fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
|
|
1654
|
+
|
|
1655
|
+
roots.set(canvas, {
|
|
1656
|
+
fiber,
|
|
1657
|
+
store
|
|
1658
|
+
}); // Store events internally
|
|
1659
|
+
|
|
1660
|
+
if (events) state.set({
|
|
1661
|
+
events: events(store)
|
|
1662
|
+
});
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
if (store && fiber) {
|
|
1666
|
+
reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
|
|
1667
|
+
store: store,
|
|
1668
|
+
element: element,
|
|
1669
|
+
onCreated: onCreated,
|
|
1670
|
+
target: canvas
|
|
1671
|
+
}), fiber, null, () => undefined);
|
|
1672
|
+
return store;
|
|
1673
|
+
} else {
|
|
1674
|
+
throw 'Error creating root!';
|
|
1675
|
+
}
|
|
1676
|
+
},
|
|
1677
|
+
unmount: () => unmountComponentAtNode(canvas)
|
|
1678
|
+
};
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
function render(element, canvas, config = {}) {
|
|
1682
|
+
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1683
|
+
return createRoot(canvas, config).render(element);
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
function Provider({
|
|
1687
|
+
store,
|
|
1688
|
+
element,
|
|
1689
|
+
onCreated,
|
|
1690
|
+
target
|
|
1691
|
+
}) {
|
|
1692
|
+
React.useEffect(() => {
|
|
1693
|
+
const state = store.getState(); // Flag the canvas active, rendering will now begin
|
|
1694
|
+
|
|
1695
|
+
state.set(state => ({
|
|
1696
|
+
internal: { ...state.internal,
|
|
1697
|
+
active: true
|
|
1698
|
+
}
|
|
1699
|
+
})); // Connect events
|
|
1700
|
+
|
|
1701
|
+
state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1702
|
+
|
|
1703
|
+
if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1704
|
+
}, []);
|
|
1705
|
+
return /*#__PURE__*/React.createElement(context.Provider, {
|
|
1706
|
+
value: store
|
|
1707
|
+
}, element);
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
function unmountComponentAtNode(canvas, callback) {
|
|
1711
|
+
const root = roots.get(canvas);
|
|
1712
|
+
const fiber = root == null ? void 0 : root.fiber;
|
|
1713
|
+
|
|
1714
|
+
if (fiber) {
|
|
1715
|
+
const state = root == null ? void 0 : root.store.getState();
|
|
1716
|
+
if (state) state.internal.active = false;
|
|
1717
|
+
reconciler.updateContainer(null, fiber, null, () => {
|
|
1718
|
+
if (state) {
|
|
1719
|
+
setTimeout(() => {
|
|
1720
|
+
try {
|
|
1721
|
+
var _state$gl, _state$gl$renderLists, _state$gl2, _state$gl3;
|
|
1722
|
+
|
|
1723
|
+
state.events.disconnect == null ? void 0 : state.events.disconnect();
|
|
1724
|
+
(_state$gl = state.gl) == null ? void 0 : (_state$gl$renderLists = _state$gl.renderLists) == null ? void 0 : _state$gl$renderLists.dispose == null ? void 0 : _state$gl$renderLists.dispose();
|
|
1725
|
+
(_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
|
|
1726
|
+
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.internal.xr.disconnect();
|
|
1727
|
+
dispose(state);
|
|
1728
|
+
roots.delete(canvas);
|
|
1729
|
+
if (callback) callback(canvas);
|
|
1730
|
+
} catch (e) {
|
|
1731
|
+
/* ... */
|
|
1732
|
+
}
|
|
1733
|
+
}, 500);
|
|
1734
|
+
}
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
const act = React.unstable_act;
|
|
1740
|
+
|
|
1741
|
+
function createPortal(children, container) {
|
|
1742
|
+
return reconciler.createPortal(children, container, null, null);
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
reconciler.injectIntoDevTools({
|
|
1746
|
+
bundleType: process.env.NODE_ENV === 'production' ? 0 : 1,
|
|
1747
|
+
rendererPackageName: '@react-three/fiber',
|
|
1748
|
+
version: '18.0.0'
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
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, useFrame as w, useGraph as x, useLoader as y };
|