@react-three/fiber 9.0.0-alpha.3 → 9.0.0-alpha.5
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 +6 -0
- package/dist/declarations/src/core/hooks.d.ts +7 -3
- package/dist/declarations/src/core/renderer.d.ts +9 -10
- package/dist/declarations/src/core/store.d.ts +6 -5
- package/dist/declarations/src/core/utils.d.ts +3 -3
- package/dist/declarations/src/native/Canvas.d.ts +1 -1
- package/dist/declarations/src/three-types.d.ts +1 -1
- package/dist/declarations/src/web/Canvas.d.ts +1 -1
- package/dist/{loop-0698c205.cjs.dev.js → loop-02cefb27.cjs.dev.js} +115 -95
- package/dist/{loop-a0ef8208.cjs.prod.js → loop-1fad3b6f.cjs.prod.js} +115 -95
- package/dist/{loop-b2aca207.esm.js → loop-d73c6316.esm.js} +115 -95
- package/dist/react-three-fiber.cjs.dev.js +2 -2
- package/dist/react-three-fiber.cjs.prod.js +2 -2
- package/dist/react-three-fiber.esm.js +3 -3
- package/native/dist/react-three-fiber-native.cjs.dev.js +5 -3
- package/native/dist/react-three-fiber-native.cjs.prod.js +5 -3
- package/native/dist/react-three-fiber-native.esm.js +7 -5
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var THREE = require('three');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var constants = require('react-reconciler/constants');
|
|
6
|
-
var
|
|
6
|
+
var traditional = require('zustand/traditional');
|
|
7
7
|
var itsFine = require('its-fine');
|
|
8
8
|
var _extends = require('@babel/runtime/helpers/extends');
|
|
9
9
|
var Reconciler = require('react-reconciler');
|
|
@@ -50,7 +50,7 @@ const extend = objects => {
|
|
|
50
50
|
catalogue[Component] = objects;
|
|
51
51
|
|
|
52
52
|
// Returns a component whose name will be inferred in devtools
|
|
53
|
-
// @ts-
|
|
53
|
+
// @ts-expect-error
|
|
54
54
|
return /*#__PURE__*/React__namespace.forwardRef({
|
|
55
55
|
[objects.name]: (props, ref) => /*#__PURE__*/React__namespace.createElement(Component, _extends({}, props, {
|
|
56
56
|
ref: ref
|
|
@@ -60,7 +60,8 @@ const extend = objects => {
|
|
|
60
60
|
return void Object.assign(catalogue, objects);
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
|
-
function createInstance(type, props, root) {
|
|
63
|
+
function createInstance(type, props, root, flushPrimitive = true) {
|
|
64
|
+
var _props$object;
|
|
64
65
|
// Get target from catalogue
|
|
65
66
|
const name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
66
67
|
const target = catalogue[name];
|
|
@@ -74,10 +75,37 @@ function createInstance(type, props, root) {
|
|
|
74
75
|
// Throw if an object or literal was passed for args
|
|
75
76
|
if (props.args !== undefined && !Array.isArray(props.args)) throw new Error('R3F: The args prop must be an array!');
|
|
76
77
|
|
|
78
|
+
// Regenerate the R3F instance for primitives to simulate a new object
|
|
79
|
+
if (flushPrimitive && type === 'primitive' && (_props$object = props.object) != null && _props$object.__r3f) delete props.object.__r3f;
|
|
80
|
+
|
|
77
81
|
// Create instance
|
|
78
82
|
const instance = prepare(props.object, root, type, props);
|
|
79
83
|
return instance;
|
|
80
84
|
}
|
|
85
|
+
function hideInstance(instance) {
|
|
86
|
+
if (!instance.isHidden) {
|
|
87
|
+
var _instance$parent;
|
|
88
|
+
if (instance.props.attach && (_instance$parent = instance.parent) != null && _instance$parent.object) {
|
|
89
|
+
detach(instance.parent, instance);
|
|
90
|
+
} else if (isObject3D(instance.object)) {
|
|
91
|
+
instance.object.visible = false;
|
|
92
|
+
}
|
|
93
|
+
instance.isHidden = true;
|
|
94
|
+
invalidateInstance(instance);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function unhideInstance(instance) {
|
|
98
|
+
if (instance.isHidden) {
|
|
99
|
+
var _instance$parent2;
|
|
100
|
+
if (instance.props.attach && (_instance$parent2 = instance.parent) != null && _instance$parent2.object) {
|
|
101
|
+
attach(instance.parent, instance);
|
|
102
|
+
} else if (isObject3D(instance.object) && instance.props.visible !== false) {
|
|
103
|
+
instance.object.visible = true;
|
|
104
|
+
}
|
|
105
|
+
instance.isHidden = false;
|
|
106
|
+
invalidateInstance(instance);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
81
109
|
|
|
82
110
|
// https://github.com/facebook/react/issues/20271
|
|
83
111
|
// This will make sure events and attach are only handled once when trees are complete
|
|
@@ -213,8 +241,19 @@ function setFiberInstance(fiber, instance) {
|
|
|
213
241
|
}
|
|
214
242
|
}
|
|
215
243
|
function switchInstance(oldInstance, type, props, fiber) {
|
|
244
|
+
// If the old instance is hidden, we need to unhide it.
|
|
245
|
+
// React assumes it can discard instances since they're pure for DOM.
|
|
246
|
+
// This isn't true for us since our lifetimes are impure and longliving.
|
|
247
|
+
// So, we manually check if an instance was hidden and unhide it.
|
|
248
|
+
if (oldInstance.isHidden) unhideInstance(oldInstance);
|
|
249
|
+
|
|
216
250
|
// Create a new instance
|
|
217
|
-
const newInstance = createInstance(type, props, oldInstance.root);
|
|
251
|
+
const newInstance = createInstance(type, props, oldInstance.root, false);
|
|
252
|
+
|
|
253
|
+
// Update attach props for primitives since we don't flush them
|
|
254
|
+
if (type === 'primitive') {
|
|
255
|
+
newInstance.props.attach = props.attach;
|
|
256
|
+
}
|
|
218
257
|
|
|
219
258
|
// Move children to new instance
|
|
220
259
|
for (const child of oldInstance.children) {
|
|
@@ -256,38 +295,15 @@ function switchInstance(oldInstance, type, props, fiber) {
|
|
|
256
295
|
const handleTextInstance = () => console.warn('R3F: Text is not allowed in JSX! This could be stray whitespace or characters.');
|
|
257
296
|
const NO_CONTEXT = {};
|
|
258
297
|
let currentUpdatePriority = constants.NoEventPriority;
|
|
259
|
-
|
|
260
|
-
// Effectively removed to diff in commit phase
|
|
261
|
-
// https://github.com/facebook/react/pull/27409
|
|
262
|
-
function prepareUpdate(instance, _type, oldProps, newProps) {
|
|
263
|
-
var _newProps$args, _oldProps$args, _newProps$args2;
|
|
264
|
-
// Reconstruct primitives if object prop changes
|
|
265
|
-
if (instance.type === 'primitive' && oldProps.object !== newProps.object) return [true];
|
|
266
|
-
|
|
267
|
-
// Throw if an object or literal was passed for args
|
|
268
|
-
if (newProps.args !== undefined && !Array.isArray(newProps.args)) throw new Error('R3F: The args prop must be an array!');
|
|
269
|
-
|
|
270
|
-
// Reconstruct instance if args change
|
|
271
|
-
if (((_newProps$args = newProps.args) == null ? void 0 : _newProps$args.length) !== ((_oldProps$args = oldProps.args) == null ? void 0 : _oldProps$args.length)) return [true];
|
|
272
|
-
if ((_newProps$args2 = newProps.args) != null && _newProps$args2.some((value, index) => {
|
|
273
|
-
var _oldProps$args2;
|
|
274
|
-
return value !== ((_oldProps$args2 = oldProps.args) == null ? void 0 : _oldProps$args2[index]);
|
|
275
|
-
})) return [true];
|
|
276
|
-
|
|
277
|
-
// Create a diff-set, flag if there are any changes
|
|
278
|
-
const changedProps = diffProps(instance, newProps, true);
|
|
279
|
-
if (Object.keys(changedProps).length) return [false, changedProps];
|
|
280
|
-
|
|
281
|
-
// Otherwise do not touch the instance
|
|
282
|
-
return null;
|
|
283
|
-
}
|
|
284
298
|
const reconciler = Reconciler__default["default"]({
|
|
285
299
|
isPrimaryRenderer: false,
|
|
286
300
|
warnsIfNotActing: false,
|
|
287
301
|
supportsMutation: true,
|
|
288
302
|
supportsPersistence: false,
|
|
289
303
|
supportsHydration: false,
|
|
290
|
-
createInstance,
|
|
304
|
+
createInstance(type, props, root) {
|
|
305
|
+
return createInstance(type, props, root);
|
|
306
|
+
},
|
|
291
307
|
removeChild,
|
|
292
308
|
appendChild,
|
|
293
309
|
appendInitialChild: appendChild,
|
|
@@ -309,18 +325,32 @@ const reconciler = Reconciler__default["default"]({
|
|
|
309
325
|
},
|
|
310
326
|
getRootHostContext: () => NO_CONTEXT,
|
|
311
327
|
getChildHostContext: () => NO_CONTEXT,
|
|
312
|
-
// @ts-
|
|
328
|
+
// @ts-expect-error prepareUpdate and updatePayload removed with React 19
|
|
313
329
|
commitUpdate(instance, type, oldProps, newProps, fiber) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
330
|
+
var _newProps$args, _oldProps$args, _newProps$args2;
|
|
331
|
+
let reconstruct = false;
|
|
332
|
+
|
|
333
|
+
// Reconstruct primitives if object prop changes
|
|
334
|
+
if (instance.type === 'primitive' && oldProps.object !== newProps.object) reconstruct = true;
|
|
335
|
+
// Reconstruct instance if args was changed to an invalid value
|
|
336
|
+
else if (newProps.args !== undefined && !Array.isArray(newProps.args)) reconstruct = true;
|
|
337
|
+
// Reconstruct instance if args were added or removed
|
|
338
|
+
else if (((_newProps$args = newProps.args) == null ? void 0 : _newProps$args.length) !== ((_oldProps$args = oldProps.args) == null ? void 0 : _oldProps$args.length)) reconstruct = true;
|
|
339
|
+
// Reconstruct instance if args were changed
|
|
340
|
+
else if ((_newProps$args2 = newProps.args) != null && _newProps$args2.some((value, index) => {
|
|
341
|
+
var _oldProps$args2;
|
|
342
|
+
return value !== ((_oldProps$args2 = oldProps.args) == null ? void 0 : _oldProps$args2[index]);
|
|
343
|
+
})) reconstruct = true;
|
|
317
344
|
|
|
318
345
|
// Reconstruct when args or <primitive object={...} have changes
|
|
319
346
|
if (reconstruct) return switchInstance(instance, type, newProps, fiber);
|
|
320
347
|
|
|
321
|
-
//
|
|
322
|
-
|
|
323
|
-
|
|
348
|
+
// Create a diff-set, flag if there are any changes
|
|
349
|
+
const changedProps = diffProps(instance, newProps);
|
|
350
|
+
if (Object.keys(changedProps).length) {
|
|
351
|
+
Object.assign(instance.props, changedProps);
|
|
352
|
+
applyProps(instance.object, changedProps);
|
|
353
|
+
}
|
|
324
354
|
},
|
|
325
355
|
finalizeInitialChildren: () => false,
|
|
326
356
|
commitMount() {},
|
|
@@ -330,28 +360,8 @@ const reconciler = Reconciler__default["default"]({
|
|
|
330
360
|
resetAfterCommit: () => {},
|
|
331
361
|
shouldSetTextContent: () => false,
|
|
332
362
|
clearContainer: () => false,
|
|
333
|
-
hideInstance
|
|
334
|
-
|
|
335
|
-
if (instance.props.attach && (_instance$parent = instance.parent) != null && _instance$parent.object) {
|
|
336
|
-
detach(instance.parent, instance);
|
|
337
|
-
} else if (isObject3D(instance.object)) {
|
|
338
|
-
instance.object.visible = false;
|
|
339
|
-
}
|
|
340
|
-
instance.isHidden = true;
|
|
341
|
-
invalidateInstance(instance);
|
|
342
|
-
},
|
|
343
|
-
unhideInstance(instance) {
|
|
344
|
-
if (instance.isHidden) {
|
|
345
|
-
var _instance$parent2;
|
|
346
|
-
if (instance.props.attach && (_instance$parent2 = instance.parent) != null && _instance$parent2.object) {
|
|
347
|
-
attach(instance.parent, instance);
|
|
348
|
-
} else if (isObject3D(instance.object) && instance.props.visible !== false) {
|
|
349
|
-
instance.object.visible = true;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
instance.isHidden = false;
|
|
353
|
-
invalidateInstance(instance);
|
|
354
|
-
},
|
|
363
|
+
hideInstance,
|
|
364
|
+
unhideInstance,
|
|
355
365
|
createTextInstance: handleTextInstance,
|
|
356
366
|
hideTextInstance: handleTextInstance,
|
|
357
367
|
unhideTextInstance: handleTextInstance,
|
|
@@ -362,7 +372,6 @@ const reconciler = Reconciler__default["default"]({
|
|
|
362
372
|
beforeActiveInstanceBlur() {},
|
|
363
373
|
afterActiveInstanceBlur() {},
|
|
364
374
|
detachDeletedInstance() {},
|
|
365
|
-
// @ts-ignore untyped react-experimental options inspired by react-art
|
|
366
375
|
// TODO: add shell types for these and upstream to DefinitelyTyped
|
|
367
376
|
// https://github.com/facebook/react/blob/main/packages/react-art/src/ReactFiberConfigART.js
|
|
368
377
|
shouldAttemptEagerTransition() {
|
|
@@ -417,8 +426,7 @@ var _window$document, _window$navigator;
|
|
|
417
426
|
*/
|
|
418
427
|
function findInitialRoot(instance) {
|
|
419
428
|
let root = instance.root;
|
|
420
|
-
|
|
421
|
-
// while (root.getState().previousRoot) root = root.getState().previousRoot!
|
|
429
|
+
while (root.getState().previousRoot) root = root.getState().previousRoot;
|
|
422
430
|
return root;
|
|
423
431
|
}
|
|
424
432
|
|
|
@@ -688,7 +696,7 @@ const RESERVED_PROPS = [...REACT_INTERNAL_PROPS,
|
|
|
688
696
|
const MEMOIZED_PROTOTYPES = new Map();
|
|
689
697
|
|
|
690
698
|
// This function prepares a set of changes to be applied to the instance
|
|
691
|
-
function diffProps(instance, newProps
|
|
699
|
+
function diffProps(instance, newProps) {
|
|
692
700
|
const changedProps = {};
|
|
693
701
|
|
|
694
702
|
// Sort through props
|
|
@@ -708,31 +716,29 @@ function diffProps(instance, newProps, resetRemoved = false) {
|
|
|
708
716
|
}
|
|
709
717
|
|
|
710
718
|
// Reset removed props for HMR
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
730
|
-
}
|
|
731
|
-
changedProps[key] = ctor[key];
|
|
732
|
-
} else {
|
|
733
|
-
// instance does not have constructor, just set it to 0
|
|
734
|
-
changedProps[key] = 0;
|
|
719
|
+
for (const prop in instance.props) {
|
|
720
|
+
if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
|
|
721
|
+
const {
|
|
722
|
+
root,
|
|
723
|
+
key
|
|
724
|
+
} = resolve(instance.object, prop);
|
|
725
|
+
|
|
726
|
+
// https://github.com/mrdoob/three.js/issues/21209
|
|
727
|
+
// HMR/fast-refresh relies on the ability to cancel out props, but threejs
|
|
728
|
+
// has no means to do this. Hence we curate a small collection of value-classes
|
|
729
|
+
// with their respective constructor/set arguments
|
|
730
|
+
// For removed props, try to set default values, if possible
|
|
731
|
+
if (root.constructor && root.constructor.length === 0) {
|
|
732
|
+
// create a blank slate of the instance and copy the particular parameter.
|
|
733
|
+
let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
|
|
734
|
+
if (!ctor) {
|
|
735
|
+
ctor = new root.constructor();
|
|
736
|
+
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
735
737
|
}
|
|
738
|
+
changedProps[key] = ctor[key];
|
|
739
|
+
} else {
|
|
740
|
+
// instance does not have constructor, just set it to 0
|
|
741
|
+
changedProps[key] = 0;
|
|
736
742
|
}
|
|
737
743
|
}
|
|
738
744
|
return changedProps;
|
|
@@ -1282,7 +1288,7 @@ function createEvents(store) {
|
|
|
1282
1288
|
const isRenderer = def => !!(def != null && def.render);
|
|
1283
1289
|
const context = /*#__PURE__*/React__namespace.createContext(null);
|
|
1284
1290
|
const createStore = (invalidate, advance) => {
|
|
1285
|
-
const rootStore =
|
|
1291
|
+
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
1286
1292
|
const position = new THREE__namespace.Vector3();
|
|
1287
1293
|
const defaultTarget = new THREE__namespace.Vector3();
|
|
1288
1294
|
const tempTarget = new THREE__namespace.Vector3();
|
|
@@ -1684,15 +1690,20 @@ const Lifecycle = [Early, Fixed, Update, Late, Render, After];
|
|
|
1684
1690
|
|
|
1685
1691
|
/**
|
|
1686
1692
|
* Exposes an object's {@link Instance}.
|
|
1687
|
-
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#
|
|
1693
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useinstancehandle
|
|
1688
1694
|
*
|
|
1689
1695
|
* **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
|
|
1690
1696
|
*/
|
|
1691
1697
|
function useInstanceHandle(ref) {
|
|
1692
1698
|
const instance = React__namespace.useRef(null);
|
|
1693
|
-
|
|
1699
|
+
React__namespace.useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
1694
1700
|
return instance;
|
|
1695
1701
|
}
|
|
1702
|
+
|
|
1703
|
+
/**
|
|
1704
|
+
* Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
|
|
1705
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
|
|
1706
|
+
*/
|
|
1696
1707
|
function useStore() {
|
|
1697
1708
|
const store = React__namespace.useContext(context);
|
|
1698
1709
|
if (!store) throw new Error('R3F: Hooks can only be used within the Canvas component!');
|
|
@@ -1704,7 +1715,6 @@ function useStore() {
|
|
|
1704
1715
|
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
|
|
1705
1716
|
*/
|
|
1706
1717
|
function useThree(selector = state => state, equalityFn) {
|
|
1707
|
-
// TODO: fix this type
|
|
1708
1718
|
return useStore()(selector, equalityFn);
|
|
1709
1719
|
}
|
|
1710
1720
|
|
|
@@ -1725,7 +1735,7 @@ function useFrame(callback, renderPriority = 0) {
|
|
|
1725
1735
|
|
|
1726
1736
|
/**
|
|
1727
1737
|
* Executes a callback in a given update stage.
|
|
1728
|
-
* Uses the stage instance to
|
|
1738
|
+
* Uses the stage instance to identify which stage to target in the lifecycle.
|
|
1729
1739
|
*/
|
|
1730
1740
|
function useUpdate(callback, stage = Stages.Update) {
|
|
1731
1741
|
const store = useStore();
|
|
@@ -1772,6 +1782,7 @@ function loadingFn(extensions, onProgress) {
|
|
|
1772
1782
|
return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => res(isObject3D(data == null ? void 0 : data.scene) ? Object.assign(data, buildGraph(data.scene)) : data), onProgress, error => reject(new Error(`Could not load ${input}: ${error == null ? void 0 : error.message}`))))));
|
|
1773
1783
|
};
|
|
1774
1784
|
}
|
|
1785
|
+
|
|
1775
1786
|
/**
|
|
1776
1787
|
* Synchronously loads and caches assets with a three loader.
|
|
1777
1788
|
*
|
|
@@ -1804,7 +1815,8 @@ useLoader.clear = function (loader, input) {
|
|
|
1804
1815
|
return suspendReact.clear([loader, ...keys]);
|
|
1805
1816
|
};
|
|
1806
1817
|
|
|
1807
|
-
//
|
|
1818
|
+
// Shim for OffscreenCanvas since it was removed from DOM types
|
|
1819
|
+
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/54988
|
|
1808
1820
|
|
|
1809
1821
|
const _roots = new Map();
|
|
1810
1822
|
const shallowLoose = {
|
|
@@ -1994,7 +2006,15 @@ function createRoot(canvas) {
|
|
|
1994
2006
|
const camera = isCamera ? cameraOptions : orthographic ? new THREE__namespace.OrthographicCamera(0, 0, 0, 0, 0.1, 1000) : new THREE__namespace.PerspectiveCamera(75, 0, 0.1, 1000);
|
|
1995
2007
|
if (!isCamera) {
|
|
1996
2008
|
camera.position.z = 5;
|
|
1997
|
-
if (cameraOptions)
|
|
2009
|
+
if (cameraOptions) {
|
|
2010
|
+
applyProps(camera, cameraOptions);
|
|
2011
|
+
// Preserve user-defined frustum if possible
|
|
2012
|
+
// https://github.com/pmndrs/react-three-fiber/issues/3160
|
|
2013
|
+
if ('aspect' in cameraOptions || 'left' in cameraOptions || 'right' in cameraOptions || 'bottom' in cameraOptions || 'top' in cameraOptions) {
|
|
2014
|
+
camera.manual = true;
|
|
2015
|
+
camera.updateProjectionMatrix();
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
1998
2018
|
// Always look at center by default
|
|
1999
2019
|
if (!state.camera && !(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
2000
2020
|
}
|
|
@@ -2291,7 +2311,7 @@ function Portal({
|
|
|
2291
2311
|
};
|
|
2292
2312
|
});
|
|
2293
2313
|
const usePortalStore = React__namespace.useMemo(() => {
|
|
2294
|
-
const store =
|
|
2314
|
+
const store = traditional.createWithEqualityFn((set, get) => ({
|
|
2295
2315
|
...rest,
|
|
2296
2316
|
set,
|
|
2297
2317
|
get
|