@react-three/fiber 8.0.0-alpha-09 → 8.0.0-beta-03

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/dist/declarations/src/core/events.d.ts +63 -59
  3. package/dist/declarations/src/core/hooks.d.ts +21 -29
  4. package/dist/declarations/src/core/loop.d.ts +12 -12
  5. package/dist/declarations/src/core/renderer.d.ts +50 -51
  6. package/dist/declarations/src/core/store.d.ts +117 -106
  7. package/dist/declarations/src/core/utils.d.ts +50 -27
  8. package/dist/declarations/src/index.d.ts +8 -7
  9. package/dist/declarations/src/native/Canvas.d.ts +16 -0
  10. package/dist/declarations/src/native/events.d.ts +6 -0
  11. package/dist/declarations/src/native/hooks.d.ts +9 -0
  12. package/dist/declarations/src/native/index.d.ts +36 -0
  13. package/dist/declarations/src/native.d.ts +8 -0
  14. package/dist/declarations/src/three-types.d.ts +309 -319
  15. package/dist/declarations/src/web/Canvas.d.ts +13 -13
  16. package/dist/declarations/src/web/events.d.ts +5 -5
  17. package/dist/declarations/src/web/index.d.ts +33 -30
  18. package/dist/hooks-15c12e3e.esm.js +1539 -0
  19. package/dist/hooks-6526f63c.cjs.dev.js +1589 -0
  20. package/dist/hooks-7b7e01e6.cjs.prod.js +1589 -0
  21. package/dist/react-three-fiber.cjs.dev.js +261 -1596
  22. package/dist/react-three-fiber.cjs.prod.js +261 -1596
  23. package/dist/react-three-fiber.esm.js +222 -1554
  24. package/native/dist/react-three-fiber-native.cjs.d.ts +1 -0
  25. package/native/dist/react-three-fiber-native.cjs.dev.js +589 -0
  26. package/native/dist/react-three-fiber-native.cjs.js +7 -0
  27. package/native/dist/react-three-fiber-native.cjs.prod.js +589 -0
  28. package/native/dist/react-three-fiber-native.esm.js +537 -0
  29. package/native/package.json +5 -0
  30. package/package.json +18 -8
  31. package/readme.md +10 -10
  32. package/__mocks__/react-use-measure/index.ts +0 -22
@@ -1,1286 +1,15 @@
1
- import * as THREE from 'three';
2
- import * as React from 'react';
3
- import { DefaultEventPriority, IdleEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
4
- import create from 'zustand';
5
- import shallow from 'zustand/shallow';
6
- import Reconciler from 'react-reconciler';
7
- import { useAsset } from 'use-asset';
8
- import mergeRefs from 'react-merge-refs';
9
- import useMeasure from 'react-use-measure';
10
-
11
- var threeTypes = /*#__PURE__*/Object.freeze({
12
- __proto__: null
13
- });
14
-
15
- const DEFAULT = '__default';
16
- const isDiffSet = def => def && !!def.memoized && !!def.changes;
17
- // A collection of compare functions
18
- const is = {
19
- obj: a => a === Object(a) && !is.arr(a) && typeof a !== 'function',
20
- fun: a => typeof a === 'function',
21
- str: a => typeof a === 'string',
22
- num: a => typeof a === 'number',
23
- und: a => a === void 0,
24
- arr: a => Array.isArray(a),
25
-
26
- equ(a, b) {
27
- // Wrong type or one of the two undefined, doesn't match
28
- if (typeof a !== typeof b || !!a !== !!b) return false; // Atomic, just compare a against b
29
-
30
- if (is.str(a) || is.num(a) || is.obj(a)) return a === b; // Array, shallow compare first to see if it's a match
31
-
32
- if (is.arr(a) && a == b) return true; // Last resort, go through keys
33
-
34
- let i;
35
-
36
- for (i in a) if (!(i in b)) return false;
37
-
38
- for (i in b) if (a[i] !== b[i]) return false;
39
-
40
- return is.und(i) ? a === b : true;
41
- }
42
-
43
- }; // Each object in the scene carries a small LocalState descriptor
44
-
45
- function prepare(object, state) {
46
- const instance = object;
47
-
48
- if (state != null && state.primitive || !instance.__r3f) {
49
- instance.__r3f = {
50
- root: null,
51
- memoizedProps: {},
52
- handlers: {
53
- count: 0
54
- },
55
- objects: [],
56
- ...state
57
- };
58
- }
59
-
60
- return object;
61
- } // Shallow check arrays, but check objects atomically
62
-
63
- function checkShallow(a, b) {
64
- if (is.arr(a) && is.equ(a, b)) return true;
65
- if (a === b) return true;
66
- return false;
67
- } // This function prepares a set of changes to be applied to the instance
68
-
69
-
70
- function diffProps(instance, {
71
- children: cN,
72
- key: kN,
73
- ref: rN,
74
- ...props
75
- }, {
76
- children: cP,
77
- key: kP,
78
- ref: rP,
79
- ...previous
80
- } = {}, remove = false) {
81
- var _instance$__r3f;
82
-
83
- const localState = (_instance$__r3f = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f : {};
84
- const entries = Object.entries(props);
85
- const changes = []; // Catch removed props, prepend them so they can be reset or removed
86
-
87
- if (remove) {
88
- const previousKeys = Object.keys(previous);
89
-
90
- for (let i = 0; i < previousKeys.length; i++) if (!props.hasOwnProperty(previousKeys[i])) entries.unshift([previousKeys[i], DEFAULT + 'remove']);
91
- }
92
-
93
- entries.forEach(([key, value]) => {
94
- var _instance$__r3f2;
95
-
96
- // Bail out on primitive object
97
- if ((_instance$__r3f2 = instance.__r3f) != null && _instance$__r3f2.primitive && key === 'object') return; // When props match bail out
98
-
99
- if (checkShallow(value, previous[key])) return;
100
- let currentInstance = instance;
101
- let targetProp = currentInstance[key]; // Collect handlers and bail out
102
-
103
- if (/^on(Pointer|Click|DoubleClick|ContextMenu|Wheel)/.test(key)) return changes.push([key, value, true, currentInstance, targetProp]); // Revolve dashed props
104
-
105
- if (key.includes('-')) {
106
- const entries = key.split('-');
107
- targetProp = entries.reduce((acc, key) => acc[key], instance); // If the target is atomic, it forces us to switch the root
108
-
109
- if (!(targetProp && targetProp.set)) {
110
- const [name, ...reverseEntries] = entries.reverse();
111
- currentInstance = reverseEntries.reverse().reduce((acc, key) => acc[key], instance);
112
- key = name;
113
- }
114
- }
115
-
116
- changes.push([key, value, false, currentInstance, targetProp]);
117
- });
118
- const memoized = { ...props
119
- };
120
- if (localState.memoizedProps && localState.memoizedProps.args) memoized.args = localState.memoizedProps.args;
121
- if (localState.memoizedProps && localState.memoizedProps.attach) memoized.attach = localState.memoizedProps.attach;
122
- return {
123
- memoized,
124
- changes
125
- };
126
- } // This function applies a set of changes to the instance
127
-
128
- function applyProps$1(instance, data) {
129
- var _instance$__r3f3, _root$getState, _localState$handlers, _localState$handlers2;
130
-
131
- // Filter equals, events and reserved props
132
- const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {};
133
- const root = localState.root;
134
- const rootState = (_root$getState = root == null ? void 0 : root.getState == null ? void 0 : root.getState()) != null ? _root$getState : {};
135
- const {
136
- memoized,
137
- changes
138
- } = isDiffSet(data) ? data : diffProps(instance, data);
139
- const prevHandlers = (_localState$handlers = localState.handlers) == null ? void 0 : _localState$handlers.count; // Prepare memoized props
140
-
141
- if (instance.__r3f) instance.__r3f.memoizedProps = memoized;
142
- changes.forEach(([key, value, isEvent, currentInstance, targetProp]) => {
143
- // https://github.com/mrdoob/three.js/issues/21209
144
- // HMR/fast-refresh relies on the ability to cancel out props, but threejs
145
- // has no means to do this. Hence we curate a small collection of value-classes
146
- // with their respective constructor/set arguments
147
- // For removed props, try to set default values, if possible
148
- if (value === DEFAULT + 'remove') {
149
- if (targetProp && targetProp.constructor) {
150
- // use the prop constructor to find the default it should be
151
- value = new targetProp.constructor(memoized.args);
152
- } else if (currentInstance.constructor) {
153
- // create a blank slate of the instance and copy the particular parameter.
154
- // @ts-ignore
155
- const defaultClassCall = new currentInstance.constructor(currentInstance.__r3f.memoizedProps.args);
156
- value = defaultClassCall[targetProp]; // destory the instance
157
-
158
- if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
159
- } else value = 0;
160
- } // Deal with pointer events ...
161
-
162
-
163
- if (isEvent) {
164
- if (value) localState.handlers[key] = value;else delete localState.handlers[key];
165
- localState.handlers.count = Object.keys(localState.handlers).length;
166
- } // Special treatment for objects with support for set/copy, and layers
167
- else if (targetProp && targetProp.set && (targetProp.copy || targetProp instanceof THREE.Layers)) {
168
- // If value is an array
169
- if (Array.isArray(value)) {
170
- if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
171
- } // Test again target.copy(class) next ...
172
- else if (targetProp.copy && value && value.constructor && targetProp.constructor.name === value.constructor.name) targetProp.copy(value); // If nothing else fits, just set the single value, ignore undefined
173
- // https://github.com/react-spring/react-three-fiber/issues/274
174
- else if (value !== undefined) {
175
- const isColor = targetProp instanceof THREE.Color; // Allow setting array scalars
176
-
177
- if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
178
- else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
179
- else targetProp.set(value); // Auto-convert sRGB colors, for now ...
180
- // https://github.com/react-spring/react-three-fiber/issues/344
181
-
182
- if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
183
- } // Else, just overwrite the value
184
-
185
- } else {
186
- currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
187
- // https://github.com/react-spring/react-three-fiber/issues/344
188
-
189
- if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) currentInstance[key].encoding = THREE.sRGBEncoding;
190
- }
191
-
192
- invalidateInstance(instance);
193
- });
194
-
195
- if (rootState.internal && instance.raycast && prevHandlers !== ((_localState$handlers2 = localState.handlers) == null ? void 0 : _localState$handlers2.count)) {
196
- // Pre-emptively remove the instance from the interaction manager
197
- const index = rootState.internal.interaction.indexOf(instance);
198
- if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
199
-
200
- if (localState.handlers.count) rootState.internal.interaction.push(instance);
201
- } // Call the update lifecycle when it is being updated, but only when it is part of the scene
202
-
203
-
204
- if (changes.length && instance.parent) updateInstance(instance);
205
- }
206
- function invalidateInstance(instance) {
207
- var _instance$__r3f4, _instance$__r3f4$root;
208
-
209
- const state = (_instance$__r3f4 = instance.__r3f) == null ? void 0 : (_instance$__r3f4$root = _instance$__r3f4.root) == null ? void 0 : _instance$__r3f4$root.getState == null ? void 0 : _instance$__r3f4$root.getState();
210
- if (state && state.internal.frames === 0) state.invalidate();
211
- }
212
- function updateInstance(instance) {
213
- instance.onUpdate == null ? void 0 : instance.onUpdate(instance);
214
- }
215
-
216
- function makeId(event) {
217
- return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
218
- }
219
-
220
- function removeInteractivity(store, object) {
221
- const {
222
- internal
223
- } = store.getState(); // Removes every trace of an object from the data store
224
-
225
- internal.interaction = internal.interaction.filter(o => o !== object);
226
- internal.initialHits = internal.initialHits.filter(o => o !== object);
227
- internal.hovered.forEach((value, key) => {
228
- if (value.eventObject === object || value.object === object) {
229
- internal.hovered.delete(key);
230
- }
231
- });
232
- }
233
- function createEvents(store) {
234
- const temp = new THREE.Vector3();
235
- /** Sets up defaultRaycaster */
236
-
237
- function prepareRay(event) {
238
- var _raycaster$computeOff;
239
-
240
- const state = store.getState();
241
- const {
242
- raycaster,
243
- mouse,
244
- camera,
245
- size
246
- } = state; // https://github.com/pmndrs/react-three-fiber/pull/782
247
- // Events trigger outside of canvas when moved
248
-
249
- const {
250
- offsetX,
251
- offsetY
252
- } = (_raycaster$computeOff = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state)) != null ? _raycaster$computeOff : event;
253
- const {
254
- width,
255
- height
256
- } = size;
257
- mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
258
- raycaster.setFromCamera(mouse, camera);
259
- }
260
- /** Calculates delta */
261
-
262
-
263
- function calculateDistance(event) {
264
- const {
265
- internal
266
- } = store.getState();
267
- const dx = event.offsetX - internal.initialClick[0];
268
- const dy = event.offsetY - internal.initialClick[1];
269
- return Math.round(Math.sqrt(dx * dx + dy * dy));
270
- }
271
- /** Returns true if an instance has a valid pointer-event registered, this excludes scroll, clicks etc */
272
-
273
-
274
- function filterPointerEvents(objects) {
275
- return objects.filter(obj => ['Move', 'Over', 'Enter', 'Out', 'Leave'].some(name => obj.__r3f.handlers['onPointer' + name]));
276
- }
277
-
278
- function intersect(filter) {
279
- const state = store.getState();
280
- const {
281
- raycaster,
282
- internal
283
- } = state; // Skip event handling when noEvents is set
284
-
285
- if (!raycaster.enabled) return [];
286
- const seen = new Set();
287
- const intersections = []; // Allow callers to eliminate event objects
288
-
289
- const eventsObjects = filter ? filter(internal.interaction) : internal.interaction; // Intersect known handler objects and filter against duplicates
290
-
291
- let intersects = raycaster.intersectObjects(eventsObjects, true).filter(item => {
292
- const id = makeId(item);
293
- if (seen.has(id)) return false;
294
- seen.add(id);
295
- return true;
296
- }); // https://github.com/mrdoob/three.js/issues/16031
297
- // Allow custom userland intersect sort order
298
-
299
- if (raycaster.filter) intersects = raycaster.filter(intersects, state);
300
-
301
- for (const intersect of intersects) {
302
- let eventObject = intersect.object; // Bubble event up
303
-
304
- while (eventObject) {
305
- if (eventObject.__r3f.handlers.count) intersections.push({ ...intersect,
306
- eventObject
307
- });
308
- eventObject = eventObject.parent;
309
- }
310
- }
311
-
312
- return intersections;
313
- }
314
- /** Creates filtered intersects and returns an array of positive hits */
315
-
316
-
317
- function patchIntersects(intersections, event) {
318
- const {
319
- internal
320
- } = store.getState(); // If the interaction is captured, make all capturing targets part of the
321
- // intersect.
322
-
323
- if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
324
- intersections.push(...internal.capturedMap.get(event.pointerId).values());
325
- }
326
-
327
- return intersections;
328
- }
329
- /** Handles intersections by forwarding them to handlers */
330
-
331
-
332
- function handleIntersects(intersections, event, callback) {
333
- const {
334
- raycaster,
335
- mouse,
336
- camera,
337
- internal
338
- } = store.getState(); // If anything has been found, forward it to the event listeners
339
-
340
- if (intersections.length) {
341
- const unprojectedPoint = temp.set(mouse.x, mouse.y, 0).unproject(camera);
342
- const delta = event.type === 'click' ? calculateDistance(event) : 0;
343
-
344
- const releasePointerCapture = id => event.target.releasePointerCapture(id);
345
-
346
- const localState = {
347
- stopped: false
348
- };
349
-
350
- for (const hit of intersections) {
351
- const hasPointerCapture = id => {
352
- var _internal$capturedMap, _internal$capturedMap2;
353
-
354
- return (_internal$capturedMap = (_internal$capturedMap2 = internal.capturedMap.get(id)) == null ? void 0 : _internal$capturedMap2.has(hit.eventObject)) != null ? _internal$capturedMap : false;
355
- };
356
-
357
- const setPointerCapture = id => {
358
- if (internal.capturedMap.has(id)) {
359
- // if the pointerId was previously captured, we add the hit to the
360
- // event capturedMap.
361
- internal.capturedMap.get(id).set(hit.eventObject, hit);
362
- } else {
363
- // if the pointerId was not previously captured, we create a map
364
- // containing the hitObject, and the hit. hitObject is used for
365
- // faster access.
366
- internal.capturedMap.set(id, new Map([[hit.eventObject, hit]]));
367
- } // Call the original event now
368
- event.target.setPointerCapture(id);
369
- }; // Add native event props
370
-
371
-
372
- let extractEventProps = {};
373
-
374
- for (let prop in Object.getPrototypeOf(event)) {
375
- let property = event[prop]; // Only copy over atomics, leave functions alone as these should be
376
- // called as event.nativeEvent.fn()
377
-
378
- if (typeof property !== 'function') extractEventProps[prop] = property;
379
- }
380
-
381
- let raycastEvent = { ...hit,
382
- ...extractEventProps,
383
- spaceX: mouse.x,
384
- spaceY: mouse.y,
385
- intersections,
386
- stopped: localState.stopped,
387
- delta,
388
- unprojectedPoint,
389
- ray: raycaster.ray,
390
- camera: camera,
391
- // Hijack stopPropagation, which just sets a flag
392
- stopPropagation: () => {
393
- // https://github.com/pmndrs/react-three-fiber/issues/596
394
- // Events are not allowed to stop propagation if the pointer has been captured
395
- const capturesForPointer = 'pointerId' in event && internal.capturedMap.get(event.pointerId); // We only authorize stopPropagation...
396
-
397
- if ( // ...if this pointer hasn't been captured
398
- !capturesForPointer || // ... or if the hit object is capturing the pointer
399
- capturesForPointer.has(hit.eventObject)) {
400
- raycastEvent.stopped = localState.stopped = true; // Propagation is stopped, remove all other hover records
401
- // An event handler is only allowed to flush other handlers if it is hovered itself
402
-
403
- if (internal.hovered.size && Array.from(internal.hovered.values()).find(i => i.eventObject === hit.eventObject)) {
404
- // Objects cannot flush out higher up objects that have already caught the event
405
- const higher = intersections.slice(0, intersections.indexOf(hit));
406
- cancelPointer([...higher, hit]);
407
- }
408
- }
409
- },
410
- // there should be a distinction between target and currentTarget
411
- target: {
412
- hasPointerCapture,
413
- setPointerCapture,
414
- releasePointerCapture
415
- },
416
- currentTarget: {
417
- hasPointerCapture,
418
- setPointerCapture,
419
- releasePointerCapture
420
- },
421
- sourceEvent: event,
422
- // deprecated
423
- nativeEvent: event
424
- }; // Call subscribers
425
-
426
- callback(raycastEvent); // Event bubbling may be interrupted by stopPropagation
427
-
428
- if (localState.stopped === true) break;
429
- }
430
- }
431
-
432
- return intersections;
433
- }
434
-
435
- function cancelPointer(hits) {
436
- const {
437
- internal
438
- } = store.getState();
439
- Array.from(internal.hovered.values()).forEach(hoveredObj => {
440
- // When no objects were hit or the the hovered object wasn't found underneath the cursor
441
- // we call onPointerOut and delete the object from the hovered-elements map
442
- if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId)) {
443
- const eventObject = hoveredObj.eventObject;
444
- const handlers = eventObject.__r3f.handlers;
445
- internal.hovered.delete(makeId(hoveredObj));
446
-
447
- if (handlers.count) {
448
- // Clear out intersects, they are outdated by now
449
- const data = { ...hoveredObj,
450
- intersections: hits || []
451
- };
452
- handlers.onPointerOut == null ? void 0 : handlers.onPointerOut(data);
453
- handlers.onPointerLeave == null ? void 0 : handlers.onPointerLeave(data);
454
- }
455
- }
456
- });
457
- }
458
-
459
- const handlePointer = name => {
460
- // Deal with cancelation
461
- switch (name) {
462
- case 'onPointerLeave':
463
- case 'onPointerCancel':
464
- return () => cancelPointer([]);
465
-
466
- case 'onLostPointerCapture':
467
- return event => {
468
- if ('pointerId' in event) {
469
- // this will be a problem if one target releases the pointerId
470
- // and another one is still keeping it, as the line below
471
- // indifferently deletes all capturing references.
472
- store.getState().internal.capturedMap.delete(event.pointerId);
473
- }
474
-
475
- cancelPointer([]);
476
- };
477
- } // Any other pointer goes here ...
478
-
479
-
480
- return event => {
481
- const {
482
- onPointerMissed,
483
- internal
484
- } = store.getState();
485
- prepareRay(event); // Get fresh intersects
486
-
487
- const isPointerMove = name === 'onPointerMove';
488
- const filter = isPointerMove ? filterPointerEvents : undefined;
489
- const hits = patchIntersects(intersect(filter), event); // Take care of unhover
490
-
491
- if (isPointerMove) cancelPointer(hits);
492
- handleIntersects(hits, event, data => {
493
- const eventObject = data.eventObject;
494
- const handlers = eventObject.__r3f.handlers; // Check presence of handlers
495
-
496
- if (!handlers.count) return;
497
-
498
- if (isPointerMove) {
499
- // Move event ...
500
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
501
- // When enter or out is present take care of hover-state
502
- const id = makeId(data);
503
- const hoveredItem = internal.hovered.get(id);
504
-
505
- if (!hoveredItem) {
506
- // If the object wasn't previously hovered, book it and call its handler
507
- internal.hovered.set(id, data);
508
- handlers.onPointerOver == null ? void 0 : handlers.onPointerOver(data);
509
- handlers.onPointerEnter == null ? void 0 : handlers.onPointerEnter(data);
510
- } else if (hoveredItem.stopped) {
511
- // If the object was previously hovered and stopped, we shouldn't allow other items to proceed
512
- data.stopPropagation();
513
- }
514
- } // Call mouse move
515
-
516
-
517
- handlers.onPointerMove == null ? void 0 : handlers.onPointerMove(data);
518
- } else {
519
- // All other events ...
520
- const handler = handlers[name];
521
-
522
- if (handler) {
523
- // Forward all events back to their respective handlers with the exception of click events,
524
- // which must use the initial target
525
- if (name !== 'onClick' && name !== 'onContextMenu' && name !== 'onDoubleClick' || internal.initialHits.includes(eventObject)) {
526
- handler(data);
527
- pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object)));
528
- }
529
- }
530
- }
531
- }); // Save initial coordinates on pointer-down
532
-
533
- if (name === 'onPointerDown') {
534
- internal.initialClick = [event.offsetX, event.offsetY];
535
- internal.initialHits = hits.map(hit => hit.eventObject);
536
- } // If a click yields no results, pass it back to the user as a miss
537
-
538
-
539
- if ((name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick') && !hits.length) {
540
- if (calculateDistance(event) <= 2) {
541
- pointerMissed(event, internal.interaction);
542
- if (onPointerMissed) onPointerMissed(event);
543
- }
544
- }
545
- };
546
- };
547
-
548
- function pointerMissed(event, objects) {
549
- objects.forEach(object => {
550
- var _r3f$handlers$onPoin, _r3f$handlers;
551
-
552
- return (_r3f$handlers$onPoin = (_r3f$handlers = object.__r3f.handlers).onPointerMissed) == null ? void 0 : _r3f$handlers$onPoin.call(_r3f$handlers, event);
553
- });
554
- }
555
-
556
- return {
557
- handlePointer
558
- };
559
- }
560
-
561
- // Type guard to tell a store from a portal
562
- const isStore = def => def && !!def.getState;
563
-
564
- const getContainer = (container, child) => {
565
- var _container$__r3f$root, _container$__r3f;
566
-
567
- return {
568
- // If the container is not a root-store then it must be a THREE.Object3D into which part of the
569
- // scene is portalled into. Now there can be two variants of this, either that object is part of
570
- // the regular jsx tree, in which case it already has __r3f with a valid root attached, or it lies
571
- // outside react, in which case we must take the root of the child that is about to be attached to it.
572
- root: isStore(container) ? container : (_container$__r3f$root = (_container$__r3f = container.__r3f) == null ? void 0 : _container$__r3f.root) != null ? _container$__r3f$root : child.__r3f.root,
573
- // The container is the eventual target into which objects are mounted, it has to be a THREE.Object3D
574
- container: isStore(container) ? container.getState().scene : container
575
- };
576
- };
577
-
578
- let catalogue = {};
579
-
580
- let extend = objects => void (catalogue = { ...catalogue,
581
- ...objects
582
- });
583
-
584
- function createRenderer(roots, getEventPriority) {
585
- function createInstance(type, {
586
- args = [],
587
- ...props
588
- }, root, hostContext, internalInstanceHandle) {
589
- let name = `${type[0].toUpperCase()}${type.slice(1)}`;
590
- let instance; // https://github.com/facebook/react/issues/17147
591
- // Portals do not give us a root, they are themselves treated as a root by the reconciler
592
- // In order to figure out the actual root we have to climb through fiber internals :(
593
-
594
- if (!isStore(root) && internalInstanceHandle) {
595
- const fn = node => {
596
- if (!node.return) return node.stateNode && node.stateNode.containerInfo;else return fn(node.return);
597
- };
598
-
599
- root = fn(internalInstanceHandle);
600
- } // Assert that by now we have a valid root
601
-
602
-
603
- if (!root || !isStore(root)) throw `No valid root for ${name}!`;
604
-
605
- if (type === 'primitive') {
606
- if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
607
- const object = props.object;
608
- instance = prepare(object, {
609
- root,
610
- primitive: true
611
- });
612
- } else {
613
- const target = catalogue[name] || THREE[name];
614
- if (!target) 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`;
615
- const isArgsArr = is.arr(args); // Instanciate new object, link it to the root
616
-
617
- instance = prepare(isArgsArr ? new target(...args) : new target(args), {
618
- root,
619
- // append memoized props with args so it's not forgotten
620
- memoizedProps: {
621
- args: isArgsArr && args.length === 0 ? null : args
622
- }
623
- });
624
- } // Auto-attach geometries and materials
625
-
626
-
627
- if (!('attachFns' in props)) {
628
- if (name.endsWith('Geometry')) {
629
- props = {
630
- attach: 'geometry',
631
- ...props
632
- };
633
- } else if (name.endsWith('Material')) {
634
- props = {
635
- attach: 'material',
636
- ...props
637
- };
638
- }
639
- } // It should NOT call onUpdate on object instanciation, because it hasn't been added to the
640
- // view yet. If the callback relies on references for instance, they won't be ready yet, this is
641
- // why it passes "true" here
642
-
643
-
644
- applyProps$1(instance, props);
645
- return instance;
646
- }
647
-
648
- function appendChild(parentInstance, child) {
649
- let addedAsChild = false;
650
-
651
- if (child) {
652
- // The attach attribute implies that the object attaches itself on the parent
653
- if (child.attachArray) {
654
- if (!is.arr(parentInstance[child.attachArray])) parentInstance[child.attachArray] = [];
655
- parentInstance[child.attachArray].push(child);
656
- } else if (child.attachObject) {
657
- if (!is.obj(parentInstance[child.attachObject[0]])) parentInstance[child.attachObject[0]] = {};
658
- parentInstance[child.attachObject[0]][child.attachObject[1]] = child;
659
- } else if (child.attach && !is.fun(child.attach)) {
660
- parentInstance[child.attach] = child;
661
- } else if (is.arr(child.attachFns)) {
662
- const [attachFn] = child.attachFns;
663
-
664
- if (is.str(attachFn) && is.fun(parentInstance[attachFn])) {
665
- parentInstance[attachFn](child);
666
- } else if (is.fun(attachFn)) {
667
- attachFn(child, parentInstance);
668
- }
669
- } else if (child.isObject3D) {
670
- // add in the usual parent-child way
671
- parentInstance.add(child);
672
- addedAsChild = true;
673
- }
674
-
675
- if (!addedAsChild) {
676
- // This is for anything that used attach, and for non-Object3Ds that don't get attached to props;
677
- // that is, anything that's a child in React but not a child in the scenegraph.
678
- parentInstance.__r3f.objects.push(child);
679
-
680
- child.parent = parentInstance;
681
- }
682
-
683
- updateInstance(child);
684
- invalidateInstance(child);
685
- }
686
- }
687
-
688
- function insertBefore(parentInstance, child, beforeChild) {
689
- let added = false;
690
-
691
- if (child) {
692
- if (child.attachArray) {
693
- const array = parentInstance[child.attachArray];
694
- if (!is.arr(array)) parentInstance[child.attachArray] = [];
695
- array.splice(array.indexOf(beforeChild), 0, child);
696
- } else if (child.attachObject || child.attach && !is.fun(child.attach)) {
697
- // attach and attachObject don't have an order anyway, so just append
698
- return appendChild(parentInstance, child);
699
- } else if (child.isObject3D) {
700
- child.parent = parentInstance;
701
- child.dispatchEvent({
702
- type: 'added'
703
- });
704
- const restSiblings = parentInstance.children.filter(sibling => sibling !== child);
705
- const index = restSiblings.indexOf(beforeChild);
706
- parentInstance.children = [...restSiblings.slice(0, index), child, ...restSiblings.slice(index)];
707
- added = true;
708
- }
709
-
710
- if (!added) {
711
- parentInstance.__r3f.objects.push(child);
712
-
713
- child.parent = parentInstance;
714
- }
715
-
716
- updateInstance(child);
717
- invalidateInstance(child);
718
- }
719
- }
720
-
721
- function removeRecursive(array, parent, dispose = false) {
722
- if (array) [...array].forEach(child => removeChild(parent, child, dispose));
723
- }
724
-
725
- function removeChild(parentInstance, child, dispose) {
726
- if (child) {
727
- var _child$__r3f2;
728
-
729
- if (parentInstance.__r3f.objects) {
730
- const oldLength = parentInstance.__r3f.objects.length;
731
- parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child);
732
- const newLength = parentInstance.__r3f.objects.length; // was it in the list?
733
-
734
- if (newLength < oldLength) {
735
- // we had also set this, so we must clear it now
736
- child.parent = null;
737
- }
738
- } // Remove attachment
739
-
740
-
741
- if (child.attachArray) {
742
- parentInstance[child.attachArray] = parentInstance[child.attachArray].filter(x => x !== child);
743
- } else if (child.attachObject) {
744
- delete parentInstance[child.attachObject[0]][child.attachObject[1]];
745
- } else if (child.attach && !is.fun(child.attach)) {
746
- parentInstance[child.attach] = null;
747
- } else if (is.arr(child.attachFns)) {
748
- const [, detachFn] = child.attachFns;
749
-
750
- if (is.str(detachFn) && is.fun(parentInstance[detachFn])) {
751
- parentInstance[detachFn](child);
752
- } else if (is.fun(detachFn)) {
753
- detachFn(child, parentInstance);
754
- }
755
- } else if (child.isObject3D) {
756
- var _child$__r3f;
757
-
758
- parentInstance.remove(child); // Remove interactivity
759
-
760
- if ((_child$__r3f = child.__r3f) != null && _child$__r3f.root) {
761
- removeInteractivity(child.__r3f.root, child);
762
- }
763
- } // Allow objects to bail out of recursive dispose alltogether by passing dispose={null}
764
- // Never dispose of primitives because their state may be kept outside of React!
765
- // In order for an object to be able to dispose it has to have
766
- // - a dispose method,
767
- // - it cannot be a <primitive object={...} />
768
- // - it cannot be a THREE.Scene, because three has broken it's own api
769
- //
770
- // Since disposal is recursive, we can check the optional dispose arg, which will be undefined
771
- // when the reconciler calls it, but then carry our own check recursively
772
-
773
-
774
- const isPrimitive = (_child$__r3f2 = child.__r3f) == null ? void 0 : _child$__r3f2.primitive;
775
- const shouldDispose = dispose === undefined ? child.dispose !== null && !isPrimitive : dispose; // Remove nested child objects. Primitives should not have objects and children that are
776
- // attached to them declaratively ...
777
-
778
- if (!isPrimitive) {
779
- var _child$__r3f3;
780
-
781
- removeRecursive((_child$__r3f3 = child.__r3f) == null ? void 0 : _child$__r3f3.objects, child, shouldDispose);
782
- removeRecursive(child.children, child, shouldDispose);
783
- } // Remove references
784
-
785
-
786
- if (child.__r3f) {
787
- delete child.__r3f.root;
788
- delete child.__r3f.objects;
789
- delete child.__r3f.handlers;
790
- delete child.__r3f.memoizedProps;
791
- if (!isPrimitive) delete child.__r3f;
792
- } // Dispose item whenever the reconciler feels like it
793
-
794
-
795
- if (shouldDispose && child.dispose && child.type !== 'Scene') {
796
- reconciler.runWithPriority(IdleEventPriority, () => {
797
- try {
798
- child.dispose();
799
- } catch (e) {
800
- /* ... */
801
- }
802
- });
803
- }
804
-
805
- invalidateInstance(parentInstance);
806
- }
807
- }
808
-
809
- function switchInstance(instance, type, newProps, fiber) {
810
- const parent = instance.parent;
811
- if (!parent) return;
812
- const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
813
- // When args change the instance has to be re-constructed, which then
814
- // forces r3f to re-parent the children and non-scene objects
815
-
816
- if (instance.children) {
817
- instance.children.forEach(child => appendChild(newInstance, child));
818
- instance.children = [];
819
- }
820
-
821
- instance.__r3f.objects.forEach(child => appendChild(newInstance, child));
822
-
823
- instance.__r3f.objects = [];
824
- removeChild(parent, instance);
825
- appendChild(parent, newInstance) // This evil hack switches the react-internal fiber node
826
- // https://github.com/facebook/react/issues/14983
827
- // https://github.com/facebook/react/pull/15021
828
- ;
829
- [fiber, fiber.alternate].forEach(fiber => {
830
- if (fiber !== null) {
831
- fiber.stateNode = newInstance;
832
-
833
- if (fiber.ref) {
834
- if (typeof fiber.ref === 'function') fiber.ref(newInstance);else fiber.ref.current = newInstance;
835
- }
836
- }
837
- });
838
- }
839
-
840
- const reconciler = Reconciler({
841
- appendChildToContainer: (parentInstance, child) => {
842
- const {
843
- container,
844
- root
845
- } = getContainer(parentInstance, child); // Link current root to the default scene
846
-
847
- container.__r3f.root = root;
848
- appendChild(container, child);
849
- },
850
- removeChildFromContainer: (parentInstance, child) => removeChild(getContainer(parentInstance, child).container, child),
851
- insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
852
-
853
- prepareUpdate(instance, type, oldProps, newProps) {
854
- if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) return [true];else {
855
- // This is a data object, let's extract critical information about it
856
- const {
857
- args: argsNew = [],
858
- children: cN,
859
- ...restNew
860
- } = newProps;
861
- const {
862
- args: argsOld = [],
863
- children: cO,
864
- ...restOld
865
- } = oldProps; // If it has new props or arguments, then it needs to be re-instanciated
866
-
867
- if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
868
-
869
- const diff = diffProps(instance, restNew, restOld, true);
870
- if (diff.changes.length) return [false, diff]; // Otherwise do not touch the instance
871
-
872
- return null;
873
- }
874
- },
875
-
876
- commitUpdate(instance, [reconstruct, diff], type, oldProps, newProps, fiber) {
877
- // Reconstruct when args or <primitive object={...} have changes
878
- if (reconstruct) switchInstance(instance, type, newProps, fiber); // Otherwise just overwrite props
879
- else applyProps$1(instance, diff);
880
- },
881
-
882
- hideInstance(instance) {
883
- if (instance.isObject3D) {
884
- instance.visible = false;
885
- invalidateInstance(instance);
886
- }
887
- },
888
-
889
- unhideInstance(instance, props) {
890
- if (instance.isObject3D && props.visible == null || props.visible) {
891
- instance.visible = true;
892
- invalidateInstance(instance);
893
- }
894
- },
895
-
896
- createInstance,
897
- removeChild,
898
- appendChild,
899
- appendInitialChild: appendChild,
900
- insertBefore,
901
- warnsIfNotActing: true,
902
- supportsMutation: true,
903
- isPrimaryRenderer: false,
904
- getCurrentEventPriority: () => getEventPriority ? getEventPriority() : DefaultEventPriority,
905
- // @ts-ignore
906
- now: is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
907
- // @ts-ignore
908
- scheduleTimeout: is.fun(setTimeout) ? setTimeout : undefined,
909
- // @ts-ignore
910
- cancelTimeout: is.fun(clearTimeout) ? clearTimeout : undefined,
911
- setTimeout: is.fun(setTimeout) ? setTimeout : undefined,
912
- clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined,
913
- noTimeout: -1,
914
- hideTextInstance: () => {
915
- throw new Error('Text is not allowed in the R3F tree.');
916
- },
917
- // prettier-ignore
918
- getPublicInstance: instance => instance,
919
- getRootHostContext: () => null,
920
- getChildHostContext: parentHostContext => parentHostContext,
921
- createTextInstance: () => {},
922
- finalizeInitialChildren: () => false,
923
- commitMount: () => {},
924
- shouldDeprioritizeSubtree: () => false,
925
- prepareForCommit: () => null,
926
- preparePortalMount: containerInfo => prepare(containerInfo),
927
- resetAfterCommit: () => {},
928
- shouldSetTextContent: () => false,
929
- clearContainer: () => false,
930
- detachDeletedInstance: () => {}
931
- });
932
- return {
933
- reconciler,
934
- applyProps: applyProps$1
935
- };
936
- }
937
-
938
- const isRenderer = def => def && !!def.render;
939
- const isOrthographicCamera = def => def && def.isOrthographicCamera;
940
- const context = /*#__PURE__*/React.createContext(null);
941
-
942
- const createStore = (applyProps, invalidate, advance, props) => {
943
- const {
944
- gl,
945
- size,
946
- shadows = false,
947
- linear = false,
948
- flat = false,
949
- vr = false,
950
- orthographic = false,
951
- frameloop = 'always',
952
- dpr = 1,
953
- performance,
954
- clock = new THREE.Clock(),
955
- raycaster: raycastOptions,
956
- camera: cameraOptions,
957
- onPointerMissed
958
- } = props; // Set shadowmap
959
-
960
- if (shadows) {
961
- gl.shadowMap.enabled = true;
962
- if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE.PCFSoftShadowMap;
963
- } // Set color management
964
-
965
-
966
- if (!linear) gl.outputEncoding = THREE.sRGBEncoding;
967
- if (!flat) gl.toneMapping = THREE.ACESFilmicToneMapping; // clock.elapsedTime is updated using advance(timestamp)
968
-
969
- if (frameloop === 'never') {
970
- clock.stop();
971
- clock.elapsedTime = 0;
972
- }
973
-
974
- const rootState = create((set, get) => {
975
- // Create custom raycaster
976
- const raycaster = new THREE.Raycaster();
977
- const {
978
- params,
979
- ...options
980
- } = raycastOptions || {};
981
- applyProps(raycaster, {
982
- enabled: true,
983
- ...options,
984
- params: { ...raycaster.params,
985
- ...params
986
- }
987
- }); // Create default camera
988
-
989
- const isCamera = cameraOptions instanceof THREE.Camera;
990
- const camera = isCamera ? cameraOptions : orthographic ? new THREE.OrthographicCamera(0, 0, 0, 0, 0.1, 1000) : new THREE.PerspectiveCamera(75, 0, 0.1, 1000);
991
-
992
- if (!isCamera) {
993
- camera.position.z = 5;
994
- if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
995
-
996
- camera.lookAt(0, 0, 0);
997
- }
998
-
999
- function setDpr(dpr) {
1000
- return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], window.devicePixelRatio), dpr[1]) : dpr;
1001
- }
1002
-
1003
- const initialDpr = setDpr(dpr);
1004
- const position = new THREE.Vector3();
1005
- const defaultTarget = new THREE.Vector3();
1006
-
1007
- function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
1008
- const {
1009
- width,
1010
- height
1011
- } = size;
1012
- const aspect = width / height;
1013
- const distance = camera.getWorldPosition(position).distanceTo(target);
1014
-
1015
- if (isOrthographicCamera(camera)) {
1016
- return {
1017
- width: width / camera.zoom,
1018
- height: height / camera.zoom,
1019
- factor: 1,
1020
- distance,
1021
- aspect
1022
- };
1023
- } else {
1024
- const fov = camera.fov * Math.PI / 180; // convert vertical fov to radians
1025
-
1026
- const h = 2 * Math.tan(fov / 2) * distance; // visible height
1027
-
1028
- const w = h * (width / height);
1029
- return {
1030
- width: w,
1031
- height: h,
1032
- factor: width / w,
1033
- distance,
1034
- aspect
1035
- };
1036
- }
1037
- }
1038
-
1039
- let performanceTimeout = undefined;
1040
-
1041
- const setPerformanceCurrent = current => set(state => ({
1042
- performance: { ...state.performance,
1043
- current
1044
- }
1045
- }));
1046
-
1047
- return {
1048
- gl,
1049
- set,
1050
- get,
1051
- invalidate: () => invalidate(get()),
1052
- advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
1053
- linear,
1054
- flat,
1055
- scene: prepare(new THREE.Scene()),
1056
- camera,
1057
- controls: null,
1058
- raycaster,
1059
- clock,
1060
- mouse: new THREE.Vector2(),
1061
- vr,
1062
- frameloop,
1063
- onPointerMissed,
1064
- performance: {
1065
- current: 1,
1066
- min: 0.5,
1067
- max: 1,
1068
- debounce: 200,
1069
- ...performance,
1070
- regress: () => {
1071
- const state = get(); // Clear timeout
1072
-
1073
- if (performanceTimeout) clearTimeout(performanceTimeout); // Set lower bound performance
1074
-
1075
- if (state.performance.current !== state.performance.min) setPerformanceCurrent(state.performance.min); // Go back to upper bound performance after a while unless something regresses meanwhile
1076
-
1077
- performanceTimeout = setTimeout(() => setPerformanceCurrent(get().performance.max), state.performance.debounce);
1078
- }
1079
- },
1080
- size: {
1081
- width: 0,
1082
- height: 0
1083
- },
1084
- viewport: {
1085
- initialDpr,
1086
- dpr: initialDpr,
1087
- width: 0,
1088
- height: 0,
1089
- aspect: 0,
1090
- distance: 0,
1091
- factor: 0,
1092
- getCurrentViewport
1093
- },
1094
- setSize: (width, height) => {
1095
- const size = {
1096
- width,
1097
- height
1098
- };
1099
- set(state => ({
1100
- size,
1101
- viewport: { ...state.viewport,
1102
- ...getCurrentViewport(camera, defaultTarget, size)
1103
- }
1104
- }));
1105
- },
1106
- setDpr: dpr => set(state => ({
1107
- viewport: { ...state.viewport,
1108
- dpr: setDpr(dpr)
1109
- }
1110
- })),
1111
- events: {
1112
- connected: false
1113
- },
1114
- internal: {
1115
- active: false,
1116
- priority: 0,
1117
- frames: 0,
1118
- lastProps: props,
1119
- interaction: [],
1120
- hovered: new Map(),
1121
- subscribers: [],
1122
- initialClick: [0, 0],
1123
- initialHits: [],
1124
- capturedMap: new Map(),
1125
- subscribe: (ref, priority = 0) => {
1126
- set(({
1127
- internal
1128
- }) => ({
1129
- internal: { ...internal,
1130
- // If this subscription was given a priority, it takes rendering into its own hands
1131
- // For that reason we switch off automatic rendering and increase the manual flag
1132
- // As long as this flag is positive there can be no internal rendering at all
1133
- // because there could be multiple render subscriptions
1134
- priority: internal.priority + (priority > 0 ? 1 : 0),
1135
- // Register subscriber and sort layers from lowest to highest, meaning,
1136
- // highest priority renders last (on top of the other frames)
1137
- subscribers: [...internal.subscribers, {
1138
- ref,
1139
- priority
1140
- }].sort((a, b) => a.priority - b.priority)
1141
- }
1142
- }));
1143
- return () => {
1144
- set(({
1145
- internal
1146
- }) => ({
1147
- internal: { ...internal,
1148
- // Decrease manual flag if this subscription had a priority
1149
- priority: internal.priority - (priority > 0 ? 1 : 0),
1150
- // Remove subscriber from list
1151
- subscribers: internal.subscribers.filter(s => s.ref !== ref)
1152
- }
1153
- }));
1154
- };
1155
- }
1156
- }
1157
- };
1158
- }); // Resize camera and renderer on changes to size and pixelratio
1159
-
1160
- rootState.subscribe(() => {
1161
- const {
1162
- camera,
1163
- size,
1164
- viewport,
1165
- internal
1166
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1167
- // Do not mess with the camera if it belongs to the user
1168
-
1169
- if (!(internal.lastProps.camera instanceof THREE.Camera)) {
1170
- if (isOrthographicCamera(camera)) {
1171
- camera.left = size.width / -2;
1172
- camera.right = size.width / 2;
1173
- camera.top = size.height / 2;
1174
- camera.bottom = size.height / -2;
1175
- } else {
1176
- camera.aspect = size.width / size.height;
1177
- }
1178
-
1179
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1180
- // Update matrix world since the renderer is a frame late
1181
-
1182
- camera.updateMatrixWorld();
1183
- } // Update renderer
1184
-
1185
-
1186
- gl.setPixelRatio(viewport.dpr);
1187
- gl.setSize(size.width, size.height);
1188
- }, state => [state.viewport.dpr, state.size], shallow);
1189
- const state = rootState.getState(); // Update size
1190
-
1191
- if (size) state.setSize(size.width, size.height); // Invalidate on any change
1192
-
1193
- rootState.subscribe(state => invalidate(state)); // Return root state
1194
-
1195
- return rootState;
1196
- };
1197
-
1198
- function createSubs(callback, subs) {
1199
- const index = subs.length;
1200
- subs.push(callback);
1201
- return () => void subs.splice(index, 1);
1202
- }
1203
-
1204
- let i;
1205
- let globalEffects = [];
1206
- let globalAfterEffects = [];
1207
- let globalTailEffects = [];
1208
- const addEffect = callback => createSubs(callback, globalEffects);
1209
- const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1210
- const addTail = callback => createSubs(callback, globalTailEffects);
1211
-
1212
- function run(effects, timestamp) {
1213
- for (i = 0; i < effects.length; i++) effects[i](timestamp);
1214
- }
1215
-
1216
- function render$1(timestamp, state) {
1217
- // Run local effects
1218
- let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
1219
-
1220
- if (state.frameloop === 'never' && typeof timestamp === 'number') {
1221
- delta = timestamp - state.clock.elapsedTime;
1222
- state.clock.oldTime = state.clock.elapsedTime;
1223
- state.clock.elapsedTime = timestamp;
1224
- } // Call subscribers (useFrame)
1225
-
1226
-
1227
- for (i = 0; i < state.internal.subscribers.length; i++) state.internal.subscribers[i].ref.current(state, delta); // Render content
1228
-
1229
-
1230
- if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
1231
-
1232
- state.internal.frames = Math.max(0, state.internal.frames - 1);
1233
- return state.frameloop === 'always' ? 1 : state.internal.frames;
1234
- }
1235
-
1236
- function createLoop(roots) {
1237
- let running = false;
1238
- let repeat;
1239
-
1240
- function loop(timestamp) {
1241
- running = true;
1242
- repeat = 0; // Run effects
1243
-
1244
- run(globalEffects, timestamp); // Render all roots
1245
-
1246
- roots.forEach(root => {
1247
- const state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
1248
-
1249
- if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0)) repeat += render$1(timestamp, state);
1250
- }); // Run after-effects
1251
-
1252
- run(globalAfterEffects, timestamp); // Keep on looping if anything invalidates the frameloop
1253
-
1254
- if (repeat > 0) return requestAnimationFrame(loop); // Tail call effects, they are called when rendering stops
1255
- else run(globalTailEffects, timestamp); // Flag end of operation
1256
-
1257
- running = false;
1258
- }
1259
-
1260
- function invalidate(state) {
1261
- if (!state) return roots.forEach(root => invalidate(root.store.getState()));
1262
- if (state.vr || !state.internal.active || state.frameloop === 'never') return; // Increase frames, do not go higher than 60
1263
-
1264
- state.internal.frames = Math.min(60, state.internal.frames + 1); // If the render-loop isn't active, start it
1265
-
1266
- if (!running) {
1267
- running = true;
1268
- requestAnimationFrame(loop);
1269
- }
1270
- }
1271
-
1272
- function advance(timestamp, runGlobalEffects = true, state) {
1273
- if (runGlobalEffects) run(globalEffects, timestamp);
1274
- if (!state) roots.forEach(root => render$1(timestamp, root.store.getState()));else render$1(timestamp, state);
1275
- if (runGlobalEffects) run(globalAfterEffects, timestamp);
1276
- }
1277
-
1278
- return {
1279
- loop,
1280
- invalidate,
1281
- advance
1282
- };
1283
- }
1
+ import { c as createEvents, a as createLoop, b as createRenderer, d as calculateDpr, e as createStore, f as context, g as dispose, i as isRenderer, h as extend, p as pick, o as omit } from './hooks-15c12e3e.esm.js';
2
+ export { t as ReactThreeFiber, k as addAfterEffect, j as addEffect, l as addTail, f as context, g as dispose, h as extend, n as useFrame, q as useGraph, r as useLoader, u as useStore, m as useThree } from './hooks-15c12e3e.esm.js';
3
+ import _extends from '@babel/runtime/helpers/esm/extends';
4
+ import * as React from 'react';
5
+ import * as THREE from 'three';
6
+ import mergeRefs from 'react-merge-refs';
7
+ import useMeasure from 'react-use-measure';
8
+ import { DefaultEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
9
+ import 'react-reconciler';
10
+ import 'scheduler';
11
+ import 'suspend-react';
12
+ import 'zustand';
1284
13
 
1285
14
  // @ts-ignore
1286
15
  const CLICK = 'click';
@@ -1389,182 +118,6 @@ function createPointerEvents(store) {
1389
118
  };
1390
119
  }
1391
120
 
1392
- // React currently throws a warning when using useLayoutEffect on the server.
1393
- // To get around it, we can conditionally useEffect on the server (no-op) and
1394
- // useLayoutEffect in the browser.
1395
- const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
1396
-
1397
- function Block({
1398
- set
1399
- }) {
1400
- useIsomorphicLayoutEffect(() => {
1401
- set(new Promise(() => null));
1402
- return () => set(false);
1403
- }, []);
1404
- return null;
1405
- }
1406
-
1407
- class ErrorBoundary extends React.Component {
1408
- constructor(...args) {
1409
- super(...args);
1410
- this.state = {
1411
- error: false
1412
- };
1413
- }
1414
-
1415
- componentDidCatch(error) {
1416
- this.props.set(error);
1417
- }
1418
-
1419
- render() {
1420
- return this.state.error ? null : this.props.children;
1421
- }
1422
-
1423
- }
1424
-
1425
- ErrorBoundary.getDerivedStateFromError = () => ({
1426
- error: true
1427
- });
1428
-
1429
- const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
1430
- children,
1431
- fallback,
1432
- tabIndex,
1433
- resize,
1434
- id,
1435
- style,
1436
- className,
1437
- events,
1438
- ...props
1439
- }, forwardedRef) {
1440
- const [containerRef, size] = useMeasure({
1441
- scroll: true,
1442
- debounce: {
1443
- scroll: 50,
1444
- resize: 0
1445
- },
1446
- ...resize
1447
- });
1448
- const canvasRef = React.useRef(null);
1449
- const [block, setBlock] = React.useState(false);
1450
- const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
1451
-
1452
- if (block) throw block; // Throw exception outwards if anything within canvas throws
1453
-
1454
- if (error) throw error; // Execute JSX in the reconciler as a layout-effect
1455
-
1456
- useIsomorphicLayoutEffect(() => {
1457
- if (size.width > 0 && size.height > 0) {
1458
- render( /*#__PURE__*/React.createElement(ErrorBoundary, {
1459
- set: setError
1460
- }, /*#__PURE__*/React.createElement(React.Suspense, {
1461
- fallback: /*#__PURE__*/React.createElement(Block, {
1462
- set: setBlock
1463
- })
1464
- }, children)), canvasRef.current, { ...props,
1465
- size,
1466
- events: events || createPointerEvents
1467
- });
1468
- }
1469
- }, [size, children]);
1470
- React.useEffect(() => {
1471
- const container = canvasRef.current;
1472
- return () => unmountComponentAtNode(container);
1473
- }, []);
1474
- return /*#__PURE__*/React.createElement("div", {
1475
- ref: containerRef,
1476
- id: id,
1477
- className: className,
1478
- tabIndex: tabIndex,
1479
- style: {
1480
- position: 'relative',
1481
- width: '100%',
1482
- height: '100%',
1483
- overflow: 'hidden',
1484
- ...style
1485
- }
1486
- }, /*#__PURE__*/React.createElement("canvas", {
1487
- ref: mergeRefs([canvasRef, forwardedRef]),
1488
- style: {
1489
- display: 'block'
1490
- }
1491
- }, fallback));
1492
- });
1493
-
1494
- function useStore() {
1495
- const store = React.useContext(context);
1496
- if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1497
- return store;
1498
- }
1499
- function useThree(selector = state => state, equalityFn) {
1500
- return useStore()(selector, equalityFn);
1501
- }
1502
- function useFrame(callback, renderPriority = 0) {
1503
- const subscribe = useStore().getState().internal.subscribe; // Update ref
1504
-
1505
- const ref = React.useRef(callback);
1506
- React.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1507
-
1508
- React.useLayoutEffect(() => subscribe(ref, renderPriority), [renderPriority, subscribe]);
1509
- return null;
1510
- }
1511
-
1512
- function buildGraph(object) {
1513
- const data = {
1514
- nodes: {},
1515
- materials: {}
1516
- };
1517
-
1518
- if (object) {
1519
- object.traverse(obj => {
1520
- if (obj.name) {
1521
- data.nodes[obj.name] = obj;
1522
- }
1523
-
1524
- if (obj.material && !data.materials[obj.material.name]) {
1525
- data.materials[obj.material.name] = obj.material;
1526
- }
1527
- });
1528
- }
1529
-
1530
- return data;
1531
- }
1532
-
1533
- function useGraph(object) {
1534
- return React.useMemo(() => buildGraph(object), [object]);
1535
- }
1536
-
1537
- function loadingFn(extensions, onProgress) {
1538
- return function (Proto, ...input) {
1539
- // Construct new loader and run extensions
1540
- const loader = new Proto();
1541
- if (extensions) extensions(loader); // Go through the urls and load them
1542
-
1543
- return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => {
1544
- if (data.scene) Object.assign(data, buildGraph(data.scene));
1545
- res(data);
1546
- }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1547
- };
1548
- }
1549
-
1550
- function useLoader(Proto, input, extensions, onProgress) {
1551
- // Use suspense to load async assets
1552
- const keys = Array.isArray(input) ? input : [input];
1553
- const results = useAsset(loadingFn(extensions, onProgress), Proto, ...keys); // Return the object/s
1554
-
1555
- return Array.isArray(input) ? results : results[0];
1556
- }
1557
-
1558
- useLoader.preload = function (Proto, input, extensions) {
1559
- const keys = Array.isArray(input) ? input : [input];
1560
- return useAsset.preload(loadingFn(extensions), Proto, ...keys);
1561
- };
1562
-
1563
- useLoader.clear = function (Proto, input) {
1564
- const keys = Array.isArray(input) ? input : [input];
1565
- return useAsset.clear(Proto, ...keys);
1566
- };
1567
-
1568
121
  const roots = new Map();
1569
122
  const {
1570
123
  invalidate,
@@ -1575,96 +128,112 @@ const {
1575
128
  applyProps
1576
129
  } = createRenderer(roots, getEventPriority);
1577
130
 
1578
- const createRendererInstance = (gl, canvas) => isRenderer(gl) ? gl : new THREE.WebGLRenderer({
1579
- powerPreference: 'high-performance',
1580
- canvas: canvas,
1581
- antialias: true,
1582
- alpha: true,
1583
- ...gl
1584
- });
131
+ const createRendererInstance = (gl, canvas) => {
132
+ const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
133
+ if (isRenderer(customRenderer)) return customRenderer;
134
+ const renderer = new THREE.WebGLRenderer({
135
+ powerPreference: 'high-performance',
136
+ canvas: canvas,
137
+ antialias: true,
138
+ alpha: true,
139
+ ...gl
140
+ }); // Set color management
141
+
142
+ renderer.outputEncoding = THREE.sRGBEncoding;
143
+ renderer.toneMapping = THREE.ACESFilmicToneMapping; // Set gl props
144
+
145
+ if (gl) applyProps(renderer, gl);
146
+ return renderer;
147
+ };
1585
148
 
1586
- function render(element, canvas, {
1587
- gl,
1588
- size,
1589
- events,
1590
- onCreated,
1591
- ...props
1592
- } = {}) {
1593
- var _store;
149
+ function createRoot(canvas, config) {
150
+ return {
151
+ render: element => {
152
+ var _store;
1594
153
 
1595
- // Allow size to take on container bounds initially
1596
- if (!size) {
1597
- var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
154
+ let {
155
+ gl,
156
+ size,
157
+ events,
158
+ onCreated,
159
+ ...props
160
+ } = config || {}; // Allow size to take on container bounds initially
1598
161
 
1599
- size = {
1600
- width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
1601
- height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
1602
- };
1603
- }
162
+ if (!size) {
163
+ var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
1604
164
 
1605
- let root = roots.get(canvas);
1606
- let fiber = root == null ? void 0 : root.fiber;
1607
- let store = root == null ? void 0 : root.store;
1608
- let state = (_store = store) == null ? void 0 : _store.getState();
165
+ size = {
166
+ width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
167
+ height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
168
+ };
169
+ }
1609
170
 
1610
- if (fiber && state) {
1611
- const lastProps = state.internal.lastProps; // When a root was found, see if any fundamental props must be changed or exchanged
1612
- // Check pixelratio
171
+ let root = roots.get(canvas);
172
+ let fiber = root == null ? void 0 : root.fiber;
173
+ let store = root == null ? void 0 : root.store;
174
+ let state = (_store = store) == null ? void 0 : _store.getState();
1613
175
 
1614
- if (props.dpr !== undefined && !is.equ(lastProps.dpr, props.dpr)) state.setDpr(props.dpr); // Check size
176
+ if (fiber && state) {
177
+ // When a root was found, see if any fundamental props must be changed or exchanged
178
+ // Check pixelratio
179
+ if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
1615
180
 
1616
- if (!is.equ(lastProps.size, size)) state.setSize(size.width, size.height); // For some props we want to reset the entire root
1617
- // Changes to the color-space
181
+ if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // Check frameloop
1618
182
 
1619
- const linearChanged = props.linear !== lastProps.linear;
183
+ if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
184
+ // Changes to the color-space
1620
185
 
1621
- if (linearChanged) {
1622
- unmountComponentAtNode(canvas);
1623
- fiber = undefined;
1624
- }
1625
- }
186
+ const linearChanged = props.linear !== state.internal.lastProps.linear;
1626
187
 
1627
- if (!fiber) {
1628
- // If no root has been found, make one
1629
- // Create gl
1630
- const glRenderer = createRendererInstance(gl, canvas); // Enable VR if requested
188
+ if (linearChanged) {
189
+ unmountComponentAtNode(canvas);
190
+ fiber = undefined;
191
+ }
192
+ }
1631
193
 
1632
- if (props.vr) {
1633
- glRenderer.xr.enabled = true;
1634
- glRenderer.setAnimationLoop(timestamp => advance(timestamp, true));
1635
- } // Create store
194
+ if (!fiber) {
195
+ // If no root has been found, make one
196
+ // Create gl
197
+ const glRenderer = createRendererInstance(gl, canvas); // Create store
1636
198
 
199
+ store = createStore(applyProps, invalidate, advance, {
200
+ gl: glRenderer,
201
+ size,
202
+ ...props
203
+ });
204
+ const state = store.getState(); // Create renderer
1637
205
 
1638
- store = createStore(applyProps, invalidate, advance, {
1639
- gl: glRenderer,
1640
- size,
1641
- ...props
1642
- });
1643
- const state = store.getState(); // Create renderer
206
+ fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
1644
207
 
1645
- fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
208
+ roots.set(canvas, {
209
+ fiber,
210
+ store
211
+ }); // Store events internally
1646
212
 
1647
- roots.set(canvas, {
1648
- fiber,
1649
- store
1650
- }); // Store events internally
213
+ if (events) state.set({
214
+ events: events(store)
215
+ });
216
+ }
1651
217
 
1652
- if (events) state.set({
1653
- events: events(store)
1654
- });
1655
- }
218
+ if (store && fiber) {
219
+ reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
220
+ store: store,
221
+ element: element,
222
+ onCreated: onCreated,
223
+ target: canvas
224
+ }), fiber, null, () => undefined);
225
+ return store;
226
+ } else {
227
+ throw 'Error creating root!';
228
+ }
229
+ },
230
+ unmount: () => unmountComponentAtNode(canvas)
231
+ };
232
+ }
1656
233
 
1657
- if (store && fiber) {
1658
- reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
1659
- store: store,
1660
- element: element,
1661
- onCreated: onCreated,
1662
- target: canvas
1663
- }), fiber, null, () => undefined);
1664
- return store;
1665
- } else {
1666
- throw 'Error creating root!';
1667
- }
234
+ function render(element, canvas, config = {}) {
235
+ console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
236
+ return createRoot(canvas, config).render(element);
1668
237
  }
1669
238
 
1670
239
  function Provider({
@@ -1684,7 +253,7 @@ function Provider({
1684
253
 
1685
254
  state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
1686
255
 
1687
- if (onCreated) onCreated(state);
256
+ if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
1688
257
  }, []);
1689
258
  return /*#__PURE__*/React.createElement(context.Provider, {
1690
259
  value: store
@@ -1701,31 +270,26 @@ function unmountComponentAtNode(canvas, callback) {
1701
270
  reconciler.updateContainer(null, fiber, null, () => {
1702
271
  if (state) {
1703
272
  setTimeout(() => {
1704
- var _state$gl, _state$gl$renderLists, _state$gl2;
1705
-
1706
- state.events.disconnect == null ? void 0 : state.events.disconnect();
1707
- (_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();
1708
- (_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
1709
- dispose(state);
1710
- roots.delete(canvas);
1711
- if (callback) callback(canvas);
273
+ try {
274
+ var _state$gl, _state$gl$renderLists, _state$gl2, _state$gl3;
275
+
276
+ state.events.disconnect == null ? void 0 : state.events.disconnect();
277
+ (_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();
278
+ (_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
279
+ if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.internal.xr.disconnect();
280
+ dispose(state);
281
+ roots.delete(canvas);
282
+ if (callback) callback(canvas);
283
+ } catch (e) {
284
+ /* ... */
285
+ }
1712
286
  }, 500);
1713
287
  }
1714
288
  });
1715
289
  }
1716
290
  }
1717
291
 
1718
- function dispose(obj) {
1719
- if (obj.dispose && obj.type !== 'Scene') obj.dispose();
1720
-
1721
- for (const p in obj) {
1722
- var _dispose, _ref;
1723
- (_dispose = (_ref = p).dispose) == null ? void 0 : _dispose.call(_ref);
1724
- delete obj[p];
1725
- }
1726
- }
1727
-
1728
- const act = reconciler.act;
292
+ const act = React.unstable_act;
1729
293
 
1730
294
  function createPortal(children, container) {
1731
295
  return reconciler.createPortal(children, container, null, null);
@@ -1734,7 +298,111 @@ function createPortal(children, container) {
1734
298
  reconciler.injectIntoDevTools({
1735
299
  bundleType: process.env.NODE_ENV === 'production' ? 0 : 1,
1736
300
  rendererPackageName: '@react-three/fiber',
1737
- version: '17.0.2'
301
+ version: '18.0.0'
302
+ });
303
+
304
+ const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'dpr', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
305
+
306
+ function Block({
307
+ set
308
+ }) {
309
+ React.useLayoutEffect(() => {
310
+ set(new Promise(() => null));
311
+ return () => set(false);
312
+ }, [set]);
313
+ return null;
314
+ }
315
+
316
+ class ErrorBoundary extends React.Component {
317
+ constructor(...args) {
318
+ super(...args);
319
+ this.state = {
320
+ error: false
321
+ };
322
+ }
323
+
324
+ componentDidCatch(error) {
325
+ this.props.set(error);
326
+ }
327
+
328
+ render() {
329
+ return this.state.error ? null : this.props.children;
330
+ }
331
+
332
+ }
333
+
334
+ ErrorBoundary.getDerivedStateFromError = () => ({
335
+ error: true
336
+ });
337
+
338
+ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
339
+ children,
340
+ fallback,
341
+ resize,
342
+ style,
343
+ events,
344
+ ...props
345
+ }, forwardedRef) {
346
+ // Create a known catalogue of Threejs-native elements
347
+ // This will include the entire THREE namespace by default, users can extend
348
+ // their own elements by using the createRoot API instead
349
+ React.useMemo(() => extend(THREE), []);
350
+ const [containerRef, {
351
+ width,
352
+ height
353
+ }] = useMeasure({
354
+ scroll: true,
355
+ debounce: {
356
+ scroll: 50,
357
+ resize: 0
358
+ },
359
+ ...resize
360
+ });
361
+ const canvasRef = React.useRef(null);
362
+ const canvasProps = pick(props, CANVAS_PROPS);
363
+ const divProps = omit(props, CANVAS_PROPS);
364
+ const [block, setBlock] = React.useState(false);
365
+ const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
366
+
367
+ if (block) throw block; // Throw exception outwards if anything within canvas throws
368
+
369
+ if (error) throw error;
370
+
371
+ if (width > 0 && height > 0) {
372
+ createRoot(canvasRef.current, { ...canvasProps,
373
+ size: {
374
+ width,
375
+ height
376
+ },
377
+ events: events || createPointerEvents
378
+ }).render( /*#__PURE__*/React.createElement(ErrorBoundary, {
379
+ set: setError
380
+ }, /*#__PURE__*/React.createElement(React.Suspense, {
381
+ fallback: /*#__PURE__*/React.createElement(Block, {
382
+ set: setBlock
383
+ })
384
+ }, children)));
385
+ }
386
+
387
+ React.useEffect(() => {
388
+ const container = canvasRef.current;
389
+ return () => unmountComponentAtNode(container);
390
+ }, []);
391
+ return /*#__PURE__*/React.createElement("div", _extends({
392
+ ref: containerRef,
393
+ style: {
394
+ position: 'relative',
395
+ width: '100%',
396
+ height: '100%',
397
+ overflow: 'hidden',
398
+ ...style
399
+ }
400
+ }, divProps), /*#__PURE__*/React.createElement("canvas", {
401
+ ref: mergeRefs([canvasRef, forwardedRef]),
402
+ style: {
403
+ display: 'block'
404
+ }
405
+ }, fallback));
1738
406
  });
1739
407
 
1740
- export { Canvas, threeTypes as ReactThreeFiber, roots as _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, context, createPortal, dispose, createPointerEvents as events, extend, invalidate, reconciler, render, unmountComponentAtNode, useFrame, useGraph, useLoader, useStore, useThree };
408
+ export { Canvas, roots as _roots, act, advance, applyProps, createPortal, createRoot, createPointerEvents as events, invalidate, reconciler, render, unmountComponentAtNode };