@react-three/fiber 9.0.0-alpha.4 → 9.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/declarations/src/core/hooks.d.ts +7 -3
- package/dist/declarations/src/core/index.d.ts +1 -1
- package/dist/declarations/src/core/reconciler.d.ts +1 -0
- package/dist/declarations/src/core/renderer.d.ts +1 -1
- package/dist/declarations/src/core/store.d.ts +16 -2
- package/dist/declarations/src/three-types.d.ts +12 -0
- package/dist/{loop-7224f71f.cjs.prod.js → loop-6e8a6208.cjs.prod.js} +194 -51
- package/dist/{loop-7f1fb121.cjs.dev.js → loop-c991cb05.cjs.dev.js} +194 -51
- package/dist/{loop-bdf826ba.esm.js → loop-ef070875.esm.js} +194 -51
- package/dist/react-three-fiber.cjs.dev.js +36 -25
- package/dist/react-three-fiber.cjs.prod.js +36 -25
- package/dist/react-three-fiber.esm.js +37 -26
- package/native/dist/react-three-fiber-native.cjs.dev.js +29 -19
- package/native/dist/react-three-fiber-native.cjs.prod.js +29 -19
- package/native/dist/react-three-fiber-native.esm.js +30 -20
- package/package.json +3 -3
- package/readme.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @react-three/fiber
|
|
2
2
|
|
|
3
|
+
## 8.16.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- cb913e01: fix: use fast JSX, future JSX types
|
|
8
|
+
|
|
9
|
+
## 8.16.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 1270d24c: fix: missing dependency on inject function
|
|
14
|
+
|
|
15
|
+
## 8.16.3
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 9c83502c: fix(Canvas): don't override camera frustum props
|
|
20
|
+
|
|
3
21
|
## 8.16.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -5,11 +5,15 @@ import { ObjectMap } from "./utils.js";
|
|
|
5
5
|
import type { Instance } from "./reconciler.js";
|
|
6
6
|
/**
|
|
7
7
|
* Exposes an object's {@link Instance}.
|
|
8
|
-
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#
|
|
8
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useinstancehandle
|
|
9
9
|
*
|
|
10
10
|
* **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
|
|
11
11
|
*/
|
|
12
|
-
export declare function useInstanceHandle<
|
|
12
|
+
export declare function useInstanceHandle<T>(ref: React.RefObject<T>): React.RefObject<Instance<T>>;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
|
|
15
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
|
|
16
|
+
*/
|
|
13
17
|
export declare function useStore(): RootStore;
|
|
14
18
|
/**
|
|
15
19
|
* Accesses R3F's internal state, containing renderer, canvas, scene, etc.
|
|
@@ -24,7 +28,7 @@ export declare function useThree<T = RootState>(selector?: (state: RootState) =>
|
|
|
24
28
|
export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
|
|
25
29
|
/**
|
|
26
30
|
* Executes a callback in a given update stage.
|
|
27
|
-
* Uses the stage instance to
|
|
31
|
+
* Uses the stage instance to identify which stage to target in the lifecycle.
|
|
28
32
|
*/
|
|
29
33
|
export declare function useUpdate(callback: UpdateCallback, stage?: StageTypes): void;
|
|
30
34
|
/**
|
|
@@ -9,7 +9,7 @@ export type { ReconcilerRoot, GLProps, CameraProps, RenderProps, InjectState } f
|
|
|
9
9
|
export { _roots, render, createRoot, unmountComponentAtNode, createPortal } from "./renderer.js";
|
|
10
10
|
export type { UpdateSubscription } from "./stages.js";
|
|
11
11
|
export { Stage, FixedStage, Stages } from "./stages.js";
|
|
12
|
-
export type { Subscription, Dpr, Size, RenderCallback, UpdateCallback, LegacyAlways, FrameloopMode, FrameloopRender, FrameloopLegacy, Frameloop, Performance, Renderer, StageTypes, XRManager, RootState, RootStore, } from "./store.js";
|
|
12
|
+
export type { Subscription, Dpr, Size, Viewport, RenderCallback, UpdateCallback, LegacyAlways, FrameloopMode, FrameloopRender, FrameloopLegacy, Frameloop, Performance, Renderer, StageTypes, XRManager, RootState, RootStore, } from "./store.js";
|
|
13
13
|
export { context } from "./store.js";
|
|
14
14
|
export type { ObjectMap, Camera, Disposable, Act } from "./utils.js";
|
|
15
15
|
export { applyProps, getRootState, dispose, act, buildGraph } from "./utils.js";
|
|
@@ -80,5 +80,5 @@ export type InjectState = Partial<Omit<RootState, 'events'> & {
|
|
|
80
80
|
connected?: any;
|
|
81
81
|
};
|
|
82
82
|
}>;
|
|
83
|
-
export declare function createPortal(children: React.ReactNode, container: THREE.Object3D, state?: InjectState): JSX.Element;
|
|
83
|
+
export declare function createPortal(children: React.ReactNode, container: THREE.Object3D, state?: InjectState): React.JSX.Element;
|
|
84
84
|
export {};
|
|
@@ -21,6 +21,18 @@ export interface Size {
|
|
|
21
21
|
top: number;
|
|
22
22
|
left: number;
|
|
23
23
|
}
|
|
24
|
+
export interface Viewport extends Size {
|
|
25
|
+
/** The initial pixel ratio */
|
|
26
|
+
initialDpr: number;
|
|
27
|
+
/** Current pixel ratio */
|
|
28
|
+
dpr: number;
|
|
29
|
+
/** size.width / viewport.width */
|
|
30
|
+
factor: number;
|
|
31
|
+
/** Camera distance */
|
|
32
|
+
distance: number;
|
|
33
|
+
/** Camera aspect ratio: width / height */
|
|
34
|
+
aspect: number;
|
|
35
|
+
}
|
|
24
36
|
export type RenderCallback = (state: RootState, delta: number, frame?: XRFrame) => void;
|
|
25
37
|
export type UpdateCallback = RenderCallback;
|
|
26
38
|
export type LegacyAlways = 'always';
|
|
@@ -106,10 +118,12 @@ export interface RootState {
|
|
|
106
118
|
frameloop: FrameloopLegacy;
|
|
107
119
|
/** Adaptive performance interface */
|
|
108
120
|
performance: Performance;
|
|
109
|
-
/** The current pixel ratio */
|
|
110
|
-
dpr: number;
|
|
111
121
|
/** Reactive pixel-size of the canvas */
|
|
112
122
|
size: Size;
|
|
123
|
+
/** Reactive size of the viewport in threejs units */
|
|
124
|
+
viewport: Viewport & {
|
|
125
|
+
getCurrentViewport: (camera?: Camera, target?: THREE.Vector3 | Parameters<THREE.Vector3['set']>, size?: Size) => Omit<Viewport, 'dpr' | 'initialDpr'>;
|
|
126
|
+
};
|
|
113
127
|
/** Flags the canvas for render, but doesn't render in itself */
|
|
114
128
|
invalidate: (frames?: number) => void;
|
|
115
129
|
/** Advance (render) one step */
|
|
@@ -53,4 +53,16 @@ declare module 'react' {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
declare module 'react/jsx-runtime' {
|
|
57
|
+
namespace JSX {
|
|
58
|
+
interface IntrinsicElements extends ThreeElements {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
declare module 'react/jsx-dev-runtime' {
|
|
63
|
+
namespace JSX {
|
|
64
|
+
interface IntrinsicElements extends ThreeElements {
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
56
68
|
export {};
|
|
@@ -5,9 +5,9 @@ var React = require('react');
|
|
|
5
5
|
var constants = require('react-reconciler/constants');
|
|
6
6
|
var traditional = require('zustand/traditional');
|
|
7
7
|
var itsFine = require('its-fine');
|
|
8
|
-
var _extends = require('@babel/runtime/helpers/extends');
|
|
9
8
|
var Reconciler = require('react-reconciler');
|
|
10
9
|
var scheduler = require('scheduler');
|
|
10
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
11
11
|
var suspendReact = require('suspend-react');
|
|
12
12
|
|
|
13
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -38,10 +38,6 @@ var threeTypes = /*#__PURE__*/Object.freeze({
|
|
|
38
38
|
__proto__: null
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
// TODO: handle constructor overloads
|
|
42
|
-
// https://github.com/pmndrs/react-three-fiber/pull/2931
|
|
43
|
-
// https://github.com/microsoft/TypeScript/issues/37079
|
|
44
|
-
|
|
45
41
|
const catalogue = {};
|
|
46
42
|
let i = 0;
|
|
47
43
|
const extend = objects => {
|
|
@@ -52,15 +48,17 @@ const extend = objects => {
|
|
|
52
48
|
// Returns a component whose name will be inferred in devtools
|
|
53
49
|
// @ts-expect-error
|
|
54
50
|
return /*#__PURE__*/React__namespace.forwardRef({
|
|
55
|
-
[objects.name]: (props, ref) => /*#__PURE__*/
|
|
51
|
+
[objects.name]: (props, ref) => /*#__PURE__*/jsxRuntime.jsx(Component, {
|
|
52
|
+
...props,
|
|
56
53
|
ref: ref
|
|
57
|
-
})
|
|
54
|
+
})
|
|
58
55
|
}[objects.name]);
|
|
59
56
|
} else {
|
|
60
57
|
return void Object.assign(catalogue, objects);
|
|
61
58
|
}
|
|
62
59
|
};
|
|
63
|
-
function createInstance(type, props, root) {
|
|
60
|
+
function createInstance(type, props, root, flushPrimitive = true) {
|
|
61
|
+
var _props$object;
|
|
64
62
|
// Get target from catalogue
|
|
65
63
|
const name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
66
64
|
const target = catalogue[name];
|
|
@@ -74,10 +72,37 @@ function createInstance(type, props, root) {
|
|
|
74
72
|
// Throw if an object or literal was passed for args
|
|
75
73
|
if (props.args !== undefined && !Array.isArray(props.args)) throw new Error('R3F: The args prop must be an array!');
|
|
76
74
|
|
|
75
|
+
// Regenerate the R3F instance for primitives to simulate a new object
|
|
76
|
+
if (flushPrimitive && type === 'primitive' && (_props$object = props.object) != null && _props$object.__r3f) delete props.object.__r3f;
|
|
77
|
+
|
|
77
78
|
// Create instance
|
|
78
79
|
const instance = prepare(props.object, root, type, props);
|
|
79
80
|
return instance;
|
|
80
81
|
}
|
|
82
|
+
function hideInstance(instance) {
|
|
83
|
+
if (!instance.isHidden) {
|
|
84
|
+
var _instance$parent;
|
|
85
|
+
if (instance.props.attach && (_instance$parent = instance.parent) != null && _instance$parent.object) {
|
|
86
|
+
detach(instance.parent, instance);
|
|
87
|
+
} else if (isObject3D(instance.object)) {
|
|
88
|
+
instance.object.visible = false;
|
|
89
|
+
}
|
|
90
|
+
instance.isHidden = true;
|
|
91
|
+
invalidateInstance(instance);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function unhideInstance(instance) {
|
|
95
|
+
if (instance.isHidden) {
|
|
96
|
+
var _instance$parent2;
|
|
97
|
+
if (instance.props.attach && (_instance$parent2 = instance.parent) != null && _instance$parent2.object) {
|
|
98
|
+
attach(instance.parent, instance);
|
|
99
|
+
} else if (isObject3D(instance.object) && instance.props.visible !== false) {
|
|
100
|
+
instance.object.visible = true;
|
|
101
|
+
}
|
|
102
|
+
instance.isHidden = false;
|
|
103
|
+
invalidateInstance(instance);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
81
106
|
|
|
82
107
|
// https://github.com/facebook/react/issues/20271
|
|
83
108
|
// This will make sure events and attach are only handled once when trees are complete
|
|
@@ -213,8 +238,19 @@ function setFiberInstance(fiber, instance) {
|
|
|
213
238
|
}
|
|
214
239
|
}
|
|
215
240
|
function switchInstance(oldInstance, type, props, fiber) {
|
|
241
|
+
// If the old instance is hidden, we need to unhide it.
|
|
242
|
+
// React assumes it can discard instances since they're pure for DOM.
|
|
243
|
+
// This isn't true for us since our lifetimes are impure and longliving.
|
|
244
|
+
// So, we manually check if an instance was hidden and unhide it.
|
|
245
|
+
if (oldInstance.isHidden) unhideInstance(oldInstance);
|
|
246
|
+
|
|
216
247
|
// Create a new instance
|
|
217
|
-
const newInstance = createInstance(type, props, oldInstance.root);
|
|
248
|
+
const newInstance = createInstance(type, props, oldInstance.root, false);
|
|
249
|
+
|
|
250
|
+
// Update attach props for primitives since we don't flush them
|
|
251
|
+
if (type === 'primitive') {
|
|
252
|
+
newInstance.props.attach = props.attach;
|
|
253
|
+
}
|
|
218
254
|
|
|
219
255
|
// Move children to new instance
|
|
220
256
|
for (const child of oldInstance.children) {
|
|
@@ -262,7 +298,9 @@ const reconciler = Reconciler__default["default"]({
|
|
|
262
298
|
supportsMutation: true,
|
|
263
299
|
supportsPersistence: false,
|
|
264
300
|
supportsHydration: false,
|
|
265
|
-
createInstance,
|
|
301
|
+
createInstance(type, props, root) {
|
|
302
|
+
return createInstance(type, props, root);
|
|
303
|
+
},
|
|
266
304
|
removeChild,
|
|
267
305
|
appendChild,
|
|
268
306
|
appendInitialChild: appendChild,
|
|
@@ -319,8 +357,8 @@ const reconciler = Reconciler__default["default"]({
|
|
|
319
357
|
resetAfterCommit: () => {},
|
|
320
358
|
shouldSetTextContent: () => false,
|
|
321
359
|
clearContainer: () => false,
|
|
322
|
-
hideInstance
|
|
323
|
-
unhideInstance
|
|
360
|
+
hideInstance,
|
|
361
|
+
unhideInstance,
|
|
324
362
|
createTextInstance: handleTextInstance,
|
|
325
363
|
hideTextInstance: handleTextInstance,
|
|
326
364
|
unhideTextInstance: handleTextInstance,
|
|
@@ -433,7 +471,11 @@ function useBridge() {
|
|
|
433
471
|
}) => {
|
|
434
472
|
const strict = !!itsFine.traverseFiber(fiber, true, node => node.type === React__namespace.StrictMode);
|
|
435
473
|
const Root = strict ? React__namespace.StrictMode : React__namespace.Fragment;
|
|
436
|
-
return /*#__PURE__*/
|
|
474
|
+
return /*#__PURE__*/jsxRuntime.jsx(Root, {
|
|
475
|
+
children: /*#__PURE__*/jsxRuntime.jsx(ContextBridge, {
|
|
476
|
+
children: children
|
|
477
|
+
})
|
|
478
|
+
});
|
|
437
479
|
}, [fiber, ContextBridge]);
|
|
438
480
|
}
|
|
439
481
|
function Block({
|
|
@@ -575,7 +617,8 @@ function prepare(target, root, type, props) {
|
|
|
575
617
|
props: getInstanceProps(props),
|
|
576
618
|
object,
|
|
577
619
|
eventCount: 0,
|
|
578
|
-
handlers: {}
|
|
620
|
+
handlers: {},
|
|
621
|
+
isHidden: false
|
|
579
622
|
};
|
|
580
623
|
if (object) {
|
|
581
624
|
object.__r3f = instance;
|
|
@@ -1247,6 +1290,44 @@ const isRenderer = def => !!(def != null && def.render);
|
|
|
1247
1290
|
const context = /*#__PURE__*/React__namespace.createContext(null);
|
|
1248
1291
|
const createStore = (invalidate, advance) => {
|
|
1249
1292
|
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
1293
|
+
const position = new THREE__namespace.Vector3();
|
|
1294
|
+
const defaultTarget = new THREE__namespace.Vector3();
|
|
1295
|
+
const tempTarget = new THREE__namespace.Vector3();
|
|
1296
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
1297
|
+
const {
|
|
1298
|
+
width,
|
|
1299
|
+
height,
|
|
1300
|
+
top,
|
|
1301
|
+
left
|
|
1302
|
+
} = size;
|
|
1303
|
+
const aspect = width / height;
|
|
1304
|
+
if (target instanceof THREE__namespace.Vector3) tempTarget.copy(target);else tempTarget.set(...target);
|
|
1305
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
1306
|
+
if (isOrthographicCamera(camera)) {
|
|
1307
|
+
return {
|
|
1308
|
+
width: width / camera.zoom,
|
|
1309
|
+
height: height / camera.zoom,
|
|
1310
|
+
top,
|
|
1311
|
+
left,
|
|
1312
|
+
factor: 1,
|
|
1313
|
+
distance,
|
|
1314
|
+
aspect
|
|
1315
|
+
};
|
|
1316
|
+
} else {
|
|
1317
|
+
const fov = camera.fov * Math.PI / 180; // convert vertical fov to radians
|
|
1318
|
+
const h = 2 * Math.tan(fov / 2) * distance; // visible height
|
|
1319
|
+
const w = h * (width / height);
|
|
1320
|
+
return {
|
|
1321
|
+
width: w,
|
|
1322
|
+
height: h,
|
|
1323
|
+
top,
|
|
1324
|
+
left,
|
|
1325
|
+
factor: width / w,
|
|
1326
|
+
distance,
|
|
1327
|
+
aspect
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1250
1331
|
let performanceTimeout = undefined;
|
|
1251
1332
|
const setPerformanceCurrent = current => set(state => ({
|
|
1252
1333
|
performance: {
|
|
@@ -1295,13 +1376,24 @@ const createStore = (invalidate, advance) => {
|
|
|
1295
1376
|
performanceTimeout = setTimeout(() => setPerformanceCurrent(get().performance.max), state.performance.debounce);
|
|
1296
1377
|
}
|
|
1297
1378
|
},
|
|
1298
|
-
dpr: 1,
|
|
1299
1379
|
size: {
|
|
1300
1380
|
width: 0,
|
|
1301
1381
|
height: 0,
|
|
1302
1382
|
top: 0,
|
|
1303
1383
|
left: 0
|
|
1304
1384
|
},
|
|
1385
|
+
viewport: {
|
|
1386
|
+
initialDpr: 0,
|
|
1387
|
+
dpr: 0,
|
|
1388
|
+
width: 0,
|
|
1389
|
+
height: 0,
|
|
1390
|
+
top: 0,
|
|
1391
|
+
left: 0,
|
|
1392
|
+
aspect: 0,
|
|
1393
|
+
distance: 0,
|
|
1394
|
+
factor: 0,
|
|
1395
|
+
getCurrentViewport
|
|
1396
|
+
},
|
|
1305
1397
|
setEvents: events => set(state => ({
|
|
1306
1398
|
...state,
|
|
1307
1399
|
events: {
|
|
@@ -1310,17 +1402,30 @@ const createStore = (invalidate, advance) => {
|
|
|
1310
1402
|
}
|
|
1311
1403
|
})),
|
|
1312
1404
|
setSize: (width, height, top = 0, left = 0) => {
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1405
|
+
const camera = get().camera;
|
|
1406
|
+
const size = {
|
|
1407
|
+
width,
|
|
1408
|
+
height,
|
|
1409
|
+
top,
|
|
1410
|
+
left
|
|
1411
|
+
};
|
|
1412
|
+
set(state => ({
|
|
1413
|
+
size,
|
|
1414
|
+
viewport: {
|
|
1415
|
+
...state.viewport,
|
|
1416
|
+
...getCurrentViewport(camera, defaultTarget, size)
|
|
1319
1417
|
}
|
|
1320
|
-
});
|
|
1418
|
+
}));
|
|
1321
1419
|
},
|
|
1322
|
-
setDpr: dpr => set({
|
|
1323
|
-
|
|
1420
|
+
setDpr: dpr => set(state => {
|
|
1421
|
+
const resolved = calculateDpr(dpr);
|
|
1422
|
+
return {
|
|
1423
|
+
viewport: {
|
|
1424
|
+
...state.viewport,
|
|
1425
|
+
dpr: resolved,
|
|
1426
|
+
initialDpr: state.viewport.initialDpr || resolved
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1324
1429
|
}),
|
|
1325
1430
|
setFrameloop: frameloop => {
|
|
1326
1431
|
var _frameloop$mode, _frameloop$render, _frameloop$maxDelta;
|
|
@@ -1409,23 +1514,39 @@ const createStore = (invalidate, advance) => {
|
|
|
1409
1514
|
});
|
|
1410
1515
|
const state = rootStore.getState();
|
|
1411
1516
|
let oldSize = state.size;
|
|
1412
|
-
let oldDpr = state.dpr;
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1517
|
+
let oldDpr = state.viewport.dpr;
|
|
1518
|
+
let oldCamera = state.camera;
|
|
1519
|
+
rootStore.subscribe(() => {
|
|
1520
|
+
const {
|
|
1521
|
+
camera,
|
|
1522
|
+
size,
|
|
1523
|
+
viewport,
|
|
1524
|
+
gl,
|
|
1525
|
+
set
|
|
1526
|
+
} = rootStore.getState();
|
|
1527
|
+
|
|
1419
1528
|
// Resize camera and renderer on changes to size and pixelratio
|
|
1420
|
-
if (size !== oldSize || dpr !== oldDpr) {
|
|
1529
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1421
1530
|
oldSize = size;
|
|
1422
|
-
oldDpr = dpr;
|
|
1531
|
+
oldDpr = viewport.dpr;
|
|
1423
1532
|
// Update camera & renderer
|
|
1424
1533
|
updateCamera(camera, size);
|
|
1425
|
-
gl.setPixelRatio(dpr);
|
|
1534
|
+
gl.setPixelRatio(viewport.dpr);
|
|
1426
1535
|
const updateStyle = typeof HTMLCanvasElement !== 'undefined' && gl.domElement instanceof HTMLCanvasElement;
|
|
1427
1536
|
gl.setSize(size.width, size.height, updateStyle);
|
|
1428
1537
|
}
|
|
1538
|
+
|
|
1539
|
+
// Update viewport once the camera changes
|
|
1540
|
+
if (camera !== oldCamera) {
|
|
1541
|
+
oldCamera = camera;
|
|
1542
|
+
// Update viewport
|
|
1543
|
+
set(state => ({
|
|
1544
|
+
viewport: {
|
|
1545
|
+
...state.viewport,
|
|
1546
|
+
...state.viewport.getCurrentViewport(camera)
|
|
1547
|
+
}
|
|
1548
|
+
}));
|
|
1549
|
+
}
|
|
1429
1550
|
});
|
|
1430
1551
|
|
|
1431
1552
|
// Invalidate on any change
|
|
@@ -1570,15 +1691,20 @@ const Lifecycle = [Early, Fixed, Update, Late, Render, After];
|
|
|
1570
1691
|
|
|
1571
1692
|
/**
|
|
1572
1693
|
* Exposes an object's {@link Instance}.
|
|
1573
|
-
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#
|
|
1694
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useinstancehandle
|
|
1574
1695
|
*
|
|
1575
1696
|
* **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
|
|
1576
1697
|
*/
|
|
1577
1698
|
function useInstanceHandle(ref) {
|
|
1578
1699
|
const instance = React__namespace.useRef(null);
|
|
1579
|
-
|
|
1700
|
+
React__namespace.useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
1580
1701
|
return instance;
|
|
1581
1702
|
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
|
|
1706
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
|
|
1707
|
+
*/
|
|
1582
1708
|
function useStore() {
|
|
1583
1709
|
const store = React__namespace.useContext(context);
|
|
1584
1710
|
if (!store) throw new Error('R3F: Hooks can only be used within the Canvas component!');
|
|
@@ -1610,7 +1736,7 @@ function useFrame(callback, renderPriority = 0) {
|
|
|
1610
1736
|
|
|
1611
1737
|
/**
|
|
1612
1738
|
* Executes a callback in a given update stage.
|
|
1613
|
-
* Uses the stage instance to
|
|
1739
|
+
* Uses the stage instance to identify which stage to target in the lifecycle.
|
|
1614
1740
|
*/
|
|
1615
1741
|
function useUpdate(callback, stage = Stages.Update) {
|
|
1616
1742
|
const store = useStore();
|
|
@@ -1657,6 +1783,7 @@ function loadingFn(extensions, onProgress) {
|
|
|
1657
1783
|
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}`))))));
|
|
1658
1784
|
};
|
|
1659
1785
|
}
|
|
1786
|
+
|
|
1660
1787
|
/**
|
|
1661
1788
|
* Synchronously loads and caches assets with a three loader.
|
|
1662
1789
|
*
|
|
@@ -1689,9 +1816,6 @@ useLoader.clear = function (loader, input) {
|
|
|
1689
1816
|
return suspendReact.clear([loader, ...keys]);
|
|
1690
1817
|
};
|
|
1691
1818
|
|
|
1692
|
-
// Shim for OffscreenCanvas since it was removed from DOM types
|
|
1693
|
-
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/54988
|
|
1694
|
-
|
|
1695
1819
|
const _roots = new Map();
|
|
1696
1820
|
const shallowLoose = {
|
|
1697
1821
|
objects: 'shallow',
|
|
@@ -1880,7 +2004,15 @@ function createRoot(canvas) {
|
|
|
1880
2004
|
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);
|
|
1881
2005
|
if (!isCamera) {
|
|
1882
2006
|
camera.position.z = 5;
|
|
1883
|
-
if (cameraOptions)
|
|
2007
|
+
if (cameraOptions) {
|
|
2008
|
+
applyProps(camera, cameraOptions);
|
|
2009
|
+
// Preserve user-defined frustum if possible
|
|
2010
|
+
// https://github.com/pmndrs/react-three-fiber/issues/3160
|
|
2011
|
+
if ('aspect' in cameraOptions || 'left' in cameraOptions || 'right' in cameraOptions || 'bottom' in cameraOptions || 'top' in cameraOptions) {
|
|
2012
|
+
camera.manual = true;
|
|
2013
|
+
camera.updateProjectionMatrix();
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
1884
2016
|
// Always look at center by default
|
|
1885
2017
|
if (!state.camera && !(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1886
2018
|
}
|
|
@@ -2009,7 +2141,7 @@ function createRoot(canvas) {
|
|
|
2009
2141
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
2010
2142
|
}
|
|
2011
2143
|
// Check pixelratio
|
|
2012
|
-
if (dpr && state.dpr !== calculateDpr(dpr)) state.setDpr(dpr);
|
|
2144
|
+
if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr);
|
|
2013
2145
|
// Check frameloop
|
|
2014
2146
|
if (state.frameloop !== frameloop) state.setFrameloop(frameloop);
|
|
2015
2147
|
// Check pointer missed
|
|
@@ -2035,7 +2167,7 @@ function createRoot(canvas) {
|
|
|
2035
2167
|
render(children) {
|
|
2036
2168
|
// The root has to be configured before it can be rendered
|
|
2037
2169
|
if (!configured) this.configure();
|
|
2038
|
-
reconciler.updateContainer( /*#__PURE__*/
|
|
2170
|
+
reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
|
|
2039
2171
|
store: store,
|
|
2040
2172
|
children: children,
|
|
2041
2173
|
onCreated: onCreated,
|
|
@@ -2076,9 +2208,10 @@ function Provider({
|
|
|
2076
2208
|
if (!store.getState().events.connected) state.events.connect == null ? void 0 : state.events.connect(rootElement);
|
|
2077
2209
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2078
2210
|
}, []);
|
|
2079
|
-
return /*#__PURE__*/
|
|
2080
|
-
value: store
|
|
2081
|
-
|
|
2211
|
+
return /*#__PURE__*/jsxRuntime.jsx(context.Provider, {
|
|
2212
|
+
value: store,
|
|
2213
|
+
children: children
|
|
2214
|
+
});
|
|
2082
2215
|
}
|
|
2083
2216
|
function unmountComponentAtNode(canvas, callback) {
|
|
2084
2217
|
const root = _roots.get(canvas);
|
|
@@ -2107,7 +2240,7 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
2107
2240
|
}
|
|
2108
2241
|
}
|
|
2109
2242
|
function createPortal(children, container, state) {
|
|
2110
|
-
return /*#__PURE__*/
|
|
2243
|
+
return /*#__PURE__*/jsxRuntime.jsx(Portal, {
|
|
2111
2244
|
children: children,
|
|
2112
2245
|
container: container,
|
|
2113
2246
|
state: state
|
|
@@ -2132,8 +2265,11 @@ function Portal({
|
|
|
2132
2265
|
const [raycaster] = React__namespace.useState(() => new THREE__namespace.Raycaster());
|
|
2133
2266
|
const [pointer] = React__namespace.useState(() => new THREE__namespace.Vector2());
|
|
2134
2267
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
2268
|
+
let viewport;
|
|
2135
2269
|
if (injectState.camera && size) {
|
|
2136
2270
|
const camera = injectState.camera;
|
|
2271
|
+
// Calculate the override viewport, if present
|
|
2272
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new THREE__namespace.Vector3(), size);
|
|
2137
2273
|
// Update the portal camera, if it differs from the previous layer
|
|
2138
2274
|
if (camera !== rootState.camera) updateCamera(camera, size);
|
|
2139
2275
|
}
|
|
@@ -2149,7 +2285,7 @@ function Portal({
|
|
|
2149
2285
|
mouse: pointer,
|
|
2150
2286
|
// Their previous root is the layer before it
|
|
2151
2287
|
previousRoot,
|
|
2152
|
-
// Events and
|
|
2288
|
+
// Events, size and viewport can be overridden by the inject layer
|
|
2153
2289
|
events: {
|
|
2154
2290
|
...rootState.events,
|
|
2155
2291
|
...injectState.events,
|
|
@@ -2159,6 +2295,10 @@ function Portal({
|
|
|
2159
2295
|
...rootState.size,
|
|
2160
2296
|
...size
|
|
2161
2297
|
},
|
|
2298
|
+
viewport: {
|
|
2299
|
+
...rootState.viewport,
|
|
2300
|
+
...viewport
|
|
2301
|
+
},
|
|
2162
2302
|
// Layers are allowed to override events
|
|
2163
2303
|
setEvents: events => injectState.set(state => ({
|
|
2164
2304
|
...state,
|
|
@@ -2183,9 +2323,12 @@ function Portal({
|
|
|
2183
2323
|
return store;
|
|
2184
2324
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2185
2325
|
}, [previousRoot, container]);
|
|
2186
|
-
return /*#__PURE__*/
|
|
2187
|
-
|
|
2188
|
-
|
|
2326
|
+
return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
2327
|
+
children: reconciler.createPortal( /*#__PURE__*/jsxRuntime.jsx(context.Provider, {
|
|
2328
|
+
value: usePortalStore,
|
|
2329
|
+
children: children
|
|
2330
|
+
}), usePortalStore, null)
|
|
2331
|
+
});
|
|
2189
2332
|
}
|
|
2190
2333
|
reconciler.injectIntoDevTools({
|
|
2191
2334
|
bundleType: 0 ,
|