@react-three/fiber 9.0.0-rc.0 → 9.0.0-rc.10

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.
@@ -1,212 +1,18 @@
1
- import { e as extend, u as useBridge, a as useMutableCallback, b as useIsomorphicLayoutEffect, c as createRoot, i as isRef, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents } from './events-5a08b43f.esm.js';
2
- export { t as ReactThreeFiber, _ as _roots, x as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, s as applyProps, y as buildGraph, q as context, g as createEvents, p as createPortal, c as createRoot, w as dispose, f as events, e as extend, h as flushGlobalEffects, v as getRootState, m as invalidate, r as reconciler, o as render, d as unmountComponentAtNode, D as useFrame, F as useGraph, z as useInstanceHandle, G as useLoader, A as useStore, C as useThree } from './events-5a08b43f.esm.js';
1
+ import { e as extend, u as useBridge, a as useMutableCallback, b as useIsomorphicLayoutEffect, c as createRoot, i as isRef, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents } from './events-aba3c3d1.esm.js';
2
+ export { t as ReactThreeFiber, _ as _roots, w as act, k as addAfterEffect, j as addEffect, l as addTail, n as advance, q as applyProps, x as buildGraph, p as context, g as createEvents, o as createPortal, c as createRoot, v as dispose, f as events, e as extend, h as flushGlobalEffects, s as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, C as useFrame, D as useGraph, y as useInstanceHandle, F as useLoader, z as useStore, A as useThree } from './events-aba3c3d1.esm.js';
3
3
  import * as React from 'react';
4
- import { useState, useRef, useEffect, useMemo } from 'react';
5
4
  import * as THREE from 'three';
6
- import createDebounce from 'debounce';
5
+ import useMeasure from 'react-use-measure';
7
6
  import { FiberProvider } from 'its-fine';
8
7
  import { jsx } from 'react/jsx-runtime';
9
8
  import 'react-reconciler/constants';
10
9
  import 'zustand/traditional';
11
- import 'suspend-react';
12
10
  import 'react-reconciler';
13
11
  import 'scheduler';
12
+ import 'suspend-react';
14
13
 
15
- /* eslint-disable react-hooks/rules-of-hooks */
16
- function useMeasure({
17
- debounce,
18
- scroll,
19
- polyfill,
20
- offsetSize
21
- } = {
22
- debounce: 0,
23
- scroll: false,
24
- offsetSize: false
25
- }) {
26
- const ResizeObserver = polyfill || typeof window !== 'undefined' && window.ResizeObserver;
27
- const [bounds, set] = useState({
28
- left: 0,
29
- top: 0,
30
- width: 0,
31
- height: 0,
32
- bottom: 0,
33
- right: 0,
34
- x: 0,
35
- y: 0
36
- });
37
-
38
- // In test mode
39
- if (!ResizeObserver) {
40
- // @ts-ignore
41
- bounds.width = 1280;
42
- // @ts-ignore
43
- bounds.height = 800;
44
- return [() => {}, bounds, () => {}];
45
- }
46
-
47
- // keep all state in a ref
48
- const state = useRef({
49
- element: null,
50
- scrollContainers: null,
51
- resizeObserver: null,
52
- lastBounds: bounds,
53
- orientationHandler: null
54
- });
55
-
56
- // set actual debounce values early, so effects know if they should react accordingly
57
- const scrollDebounce = debounce ? typeof debounce === 'number' ? debounce : debounce.scroll : null;
58
- const resizeDebounce = debounce ? typeof debounce === 'number' ? debounce : debounce.resize : null;
59
-
60
- // make sure to update state only as long as the component is truly mounted
61
- const mounted = useRef(false);
62
- useEffect(() => {
63
- mounted.current = true;
64
- return () => void (mounted.current = false);
65
- });
66
-
67
- // memoize handlers, so event-listeners know when they should update
68
- const [forceRefresh, resizeChange, scrollChange] = useMemo(() => {
69
- const callback = () => {
70
- if (!state.current.element) return;
71
- const {
72
- left,
73
- top,
74
- width,
75
- height,
76
- bottom,
77
- right,
78
- x,
79
- y
80
- } = state.current.element.getBoundingClientRect();
81
- const size = {
82
- left,
83
- top,
84
- width,
85
- height,
86
- bottom,
87
- right,
88
- x,
89
- y
90
- };
91
- if (state.current.element instanceof HTMLElement && offsetSize) {
92
- size.height = state.current.element.offsetHeight;
93
- size.width = state.current.element.offsetWidth;
94
- }
95
- Object.freeze(size);
96
- if (mounted.current && !areBoundsEqual(state.current.lastBounds, size)) set(state.current.lastBounds = size);
97
- };
98
- return [callback, resizeDebounce ? createDebounce(callback, resizeDebounce) : callback, scrollDebounce ? createDebounce(callback, scrollDebounce) : callback];
99
- }, [set, offsetSize, scrollDebounce, resizeDebounce]);
100
-
101
- // cleanup current scroll-listeners / observers
102
- function removeListeners() {
103
- if (state.current.scrollContainers) {
104
- state.current.scrollContainers.forEach(element => element.removeEventListener('scroll', scrollChange, true));
105
- state.current.scrollContainers = null;
106
- }
107
- if (state.current.resizeObserver) {
108
- state.current.resizeObserver.disconnect();
109
- state.current.resizeObserver = null;
110
- }
111
- if (state.current.orientationHandler) {
112
- if ('orientation' in screen && 'removeEventListener' in screen.orientation) {
113
- screen.orientation.removeEventListener('change', state.current.orientationHandler);
114
- } else if ('onorientationchange' in window) {
115
- window.removeEventListener('orientationchange', state.current.orientationHandler);
116
- }
117
- }
118
- }
119
-
120
- // add scroll-listeners / observers
121
- function addListeners() {
122
- var _state$current$resize;
123
- if (!state.current.element) return;
124
- state.current.resizeObserver = new ResizeObserver(resizeChange);
125
- (_state$current$resize = state.current.resizeObserver) == null ? void 0 : _state$current$resize.observe(state.current.element);
126
- if (scroll && state.current.scrollContainers) {
127
- state.current.scrollContainers.forEach(scrollContainer => scrollContainer.addEventListener('scroll', scrollChange, {
128
- capture: true,
129
- passive: true
130
- }));
131
- }
132
-
133
- // Handle orientation changes
134
- state.current.orientationHandler = () => {
135
- scrollChange();
136
- };
137
-
138
- // Use screen.orientation if available
139
- if ('orientation' in screen && 'addEventListener' in screen.orientation) {
140
- screen.orientation.addEventListener('change', state.current.orientationHandler);
141
- } else if ('onorientationchange' in window) {
142
- // Fallback to orientationchange event
143
- window.addEventListener('orientationchange', state.current.orientationHandler);
144
- }
145
- }
146
-
147
- // the ref we expose to the user
148
- const ref = node => {
149
- if (!node || node === state.current.element) return;
150
- removeListeners();
151
- state.current.element = node;
152
- state.current.scrollContainers = findScrollContainers(node);
153
- addListeners();
154
- };
155
-
156
- // add general event listeners
157
- useOnWindowScroll(scrollChange, Boolean(scroll));
158
- useOnWindowResize(resizeChange);
159
-
160
- // respond to changes that are relevant for the listeners
161
- useEffect(() => {
162
- removeListeners();
163
- addListeners();
164
- }, [scroll, scrollChange, resizeChange]);
165
-
166
- // remove all listeners when the components unmounts
167
- useEffect(() => removeListeners, []);
168
- return [ref, bounds, forceRefresh];
169
- }
170
-
171
- // Adds native resize listener to window
172
- function useOnWindowResize(onWindowResize) {
173
- useEffect(() => {
174
- const cb = onWindowResize;
175
- window.addEventListener('resize', cb);
176
- return () => void window.removeEventListener('resize', cb);
177
- }, [onWindowResize]);
178
- }
179
- function useOnWindowScroll(onScroll, enabled) {
180
- useEffect(() => {
181
- if (enabled) {
182
- const cb = onScroll;
183
- window.addEventListener('scroll', cb, {
184
- capture: true,
185
- passive: true
186
- });
187
- return () => void window.removeEventListener('scroll', cb, true);
188
- }
189
- }, [onScroll, enabled]);
190
- }
191
-
192
- // Returns a list of scroll offsets
193
- function findScrollContainers(element) {
194
- const result = [];
195
- if (!element || element === document.body) return result;
196
- const {
197
- overflow,
198
- overflowX,
199
- overflowY
200
- } = window.getComputedStyle(element);
201
- if ([overflow, overflowX, overflowY].some(prop => prop === 'auto' || prop === 'scroll')) result.push(element);
202
- return [...result, ...findScrollContainers(element.parentElement)];
203
- }
204
-
205
- // Checks if element boundaries are equal
206
- const keys = ['x', 'y', 'top', 'bottom', 'left', 'right', 'width', 'height'];
207
- const areBoundsEqual = (a, b) => keys.every(key => a[key] === b[key]);
208
-
209
- const CanvasImpl = /*#__PURE__*/React.forwardRef(function Canvas({
14
+ function CanvasImpl({
15
+ ref,
210
16
  children,
211
17
  fallback,
212
18
  resize,
@@ -229,7 +35,7 @@ const CanvasImpl = /*#__PURE__*/React.forwardRef(function Canvas({
229
35
  onPointerMissed,
230
36
  onCreated,
231
37
  ...props
232
- }, forwardedRef) {
38
+ }) {
233
39
  // Create a known catalogue of Threejs-native elements
234
40
  // This will include the entire THREE namespace by default, users can extend
235
41
  // their own elements by using the createRoot API instead
@@ -245,7 +51,7 @@ const CanvasImpl = /*#__PURE__*/React.forwardRef(function Canvas({
245
51
  });
246
52
  const canvasRef = React.useRef(null);
247
53
  const divRef = React.useRef(null);
248
- React.useImperativeHandle(forwardedRef, () => canvasRef.current);
54
+ React.useImperativeHandle(ref, () => canvasRef.current);
249
55
  const handlePointerMissed = useMutableCallback(onPointerMissed);
250
56
  const [block, setBlock] = React.useState(false);
251
57
  const [error, setError] = React.useState(false);
@@ -259,52 +65,55 @@ const CanvasImpl = /*#__PURE__*/React.forwardRef(function Canvas({
259
65
  const canvas = canvasRef.current;
260
66
  if (containerRect.width > 0 && containerRect.height > 0 && canvas) {
261
67
  if (!root.current) root.current = createRoot(canvas);
262
- root.current.configure({
263
- gl,
264
- scene,
265
- events,
266
- shadows,
267
- linear,
268
- flat,
269
- legacy,
270
- orthographic,
271
- frameloop,
272
- dpr,
273
- performance,
274
- raycaster,
275
- camera,
276
- size: containerRect,
277
- // Pass mutable reference to onPointerMissed so it's free to update
278
- onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
279
- onCreated: state => {
280
- // Connect to event source
281
- state.events.connect == null ? void 0 : state.events.connect(eventSource ? isRef(eventSource) ? eventSource.current : eventSource : divRef.current);
282
- // Set up compute function
283
- if (eventPrefix) {
284
- state.setEvents({
285
- compute: (event, state) => {
286
- const x = event[eventPrefix + 'X'];
287
- const y = event[eventPrefix + 'Y'];
288
- state.pointer.set(x / state.size.width * 2 - 1, -(y / state.size.height) * 2 + 1);
289
- state.raycaster.setFromCamera(state.pointer, state.camera);
290
- }
291
- });
68
+ async function run() {
69
+ await root.current.configure({
70
+ gl,
71
+ scene,
72
+ events,
73
+ shadows,
74
+ linear,
75
+ flat,
76
+ legacy,
77
+ orthographic,
78
+ frameloop,
79
+ dpr,
80
+ performance,
81
+ raycaster,
82
+ camera,
83
+ size: containerRect,
84
+ // Pass mutable reference to onPointerMissed so it's free to update
85
+ onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
86
+ onCreated: state => {
87
+ // Connect to event source
88
+ state.events.connect == null ? void 0 : state.events.connect(eventSource ? isRef(eventSource) ? eventSource.current : eventSource : divRef.current);
89
+ // Set up compute function
90
+ if (eventPrefix) {
91
+ state.setEvents({
92
+ compute: (event, state) => {
93
+ const x = event[eventPrefix + 'X'];
94
+ const y = event[eventPrefix + 'Y'];
95
+ state.pointer.set(x / state.size.width * 2 - 1, -(y / state.size.height) * 2 + 1);
96
+ state.raycaster.setFromCamera(state.pointer, state.camera);
97
+ }
98
+ });
99
+ }
100
+ // Call onCreated callback
101
+ onCreated == null ? void 0 : onCreated(state);
292
102
  }
293
- // Call onCreated callback
294
- onCreated == null ? void 0 : onCreated(state);
295
- }
296
- });
297
- root.current.render( /*#__PURE__*/jsx(Bridge, {
298
- children: /*#__PURE__*/jsx(ErrorBoundary, {
299
- set: setError,
300
- children: /*#__PURE__*/jsx(React.Suspense, {
301
- fallback: /*#__PURE__*/jsx(Block, {
302
- set: setBlock
303
- }),
304
- children: children
103
+ });
104
+ root.current.render( /*#__PURE__*/jsx(Bridge, {
105
+ children: /*#__PURE__*/jsx(ErrorBoundary, {
106
+ set: setError,
107
+ children: /*#__PURE__*/jsx(React.Suspense, {
108
+ fallback: /*#__PURE__*/jsx(Block, {
109
+ set: setBlock
110
+ }),
111
+ children: children
112
+ })
305
113
  })
306
- })
307
- }));
114
+ }));
115
+ }
116
+ run();
308
117
  }
309
118
  });
310
119
  React.useEffect(() => {
@@ -341,19 +150,18 @@ const CanvasImpl = /*#__PURE__*/React.forwardRef(function Canvas({
341
150
  })
342
151
  })
343
152
  });
344
- });
153
+ }
345
154
 
346
155
  /**
347
156
  * A DOM canvas which accepts threejs elements as children.
348
157
  * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
349
158
  */
350
- const Canvas = /*#__PURE__*/React.forwardRef(function CanvasWrapper(props, ref) {
159
+ function Canvas(props) {
351
160
  return /*#__PURE__*/jsx(FiberProvider, {
352
161
  children: /*#__PURE__*/jsx(CanvasImpl, {
353
- ...props,
354
- ref: ref
162
+ ...props
355
163
  })
356
164
  });
357
- });
165
+ }
358
166
 
359
167
  export { Canvas };
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var events = require('../../dist/events-fa0fb3db.cjs.dev.js');
5
+ var events = require('../../dist/events-b02714fc.cjs.dev.js');
6
6
  var React = require('react');
7
7
  var THREE = require('three');
8
8
  var reactNative = require('react-native');
@@ -15,9 +15,9 @@ var base64Js = require('base64-js');
15
15
  var buffer = require('buffer');
16
16
  require('react-reconciler/constants');
17
17
  require('zustand/traditional');
18
- require('suspend-react');
19
18
  require('react-reconciler');
20
19
  require('scheduler');
20
+ require('suspend-react');
21
21
 
22
22
  function _interopNamespace(e) {
23
23
  if (e && e.__esModule) return e;
@@ -43,11 +43,7 @@ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
43
43
 
44
44
  // TODO: React 19 needs support from react-native
45
45
  const _View = reactNative.View;
46
- /**
47
- * A native canvas which accepts threejs elements as children.
48
- * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
49
- */
50
- const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(({
46
+ function CanvasImpl({
51
47
  children,
52
48
  style,
53
49
  gl,
@@ -64,8 +60,9 @@ const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(({
64
60
  scene,
65
61
  onPointerMissed,
66
62
  onCreated,
63
+ ref,
67
64
  ...props
68
- }, forwardedRef) => {
65
+ }) {
69
66
  // Create a known catalogue of Threejs-native elements
70
67
  // This will include the entire THREE namespace by default, users can extend
71
68
  // their own elements by using the createRoot API instead
@@ -84,7 +81,7 @@ const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(({
84
81
  });
85
82
  const [canvas, setCanvas] = React__namespace.useState(null);
86
83
  const [bind, setBind] = React__namespace.useState();
87
- React__namespace.useImperativeHandle(forwardedRef, () => viewRef.current);
84
+ React__namespace.useImperativeHandle(ref, () => viewRef.current);
88
85
  const handlePointerMissed = events.useMutableCallback(onPointerMissed);
89
86
  const [block, setBlock] = React__namespace.useState(false);
90
87
  const [error, setError] = React__namespace.useState(undefined);
@@ -196,55 +193,60 @@ const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(({
196
193
  });
197
194
  setBind(responder.panHandlers);
198
195
  }, []);
199
- if (root.current && width > 0 && height > 0) {
200
- root.current.configure({
201
- gl,
202
- events: events$1,
203
- shadows,
204
- linear,
205
- flat,
206
- legacy,
207
- orthographic,
208
- frameloop,
209
- performance,
210
- raycaster,
211
- camera,
212
- scene,
213
- // expo-gl can only render at native dpr/resolution
214
- // https://github.com/expo/expo-three/issues/39
215
- dpr: reactNative.PixelRatio.get(),
216
- size: {
217
- width,
218
- height,
219
- top,
220
- left
221
- },
222
- // Pass mutable reference to onPointerMissed so it's free to update
223
- onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
224
- // Overwrite onCreated to apply RN bindings
225
- onCreated: state => {
226
- // Bind render to RN bridge
227
- const context = state.gl.getContext();
228
- const renderFrame = state.gl.render.bind(state.gl);
229
- state.gl.render = (scene, camera) => {
230
- renderFrame(scene, camera);
231
- context.endFrameEXP();
232
- };
233
- return onCreated == null ? void 0 : onCreated(state);
196
+ events.useIsomorphicLayoutEffect(() => {
197
+ if (root.current && width > 0 && height > 0) {
198
+ async function run() {
199
+ await root.current.configure({
200
+ gl,
201
+ events: events$1,
202
+ shadows,
203
+ linear,
204
+ flat,
205
+ legacy,
206
+ orthographic,
207
+ frameloop,
208
+ performance,
209
+ raycaster,
210
+ camera,
211
+ scene,
212
+ // expo-gl can only render at native dpr/resolution
213
+ // https://github.com/expo/expo-three/issues/39
214
+ dpr: reactNative.PixelRatio.get(),
215
+ size: {
216
+ width,
217
+ height,
218
+ top,
219
+ left
220
+ },
221
+ // Pass mutable reference to onPointerMissed so it's free to update
222
+ onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
223
+ // Overwrite onCreated to apply RN bindings
224
+ onCreated: state => {
225
+ // Bind render to RN bridge
226
+ const context = state.gl.getContext();
227
+ const renderFrame = state.gl.render.bind(state.gl);
228
+ state.gl.render = (scene, camera) => {
229
+ renderFrame(scene, camera);
230
+ context.endFrameEXP();
231
+ };
232
+ return onCreated == null ? void 0 : onCreated(state);
233
+ }
234
+ });
235
+ root.current.render( /*#__PURE__*/jsxRuntime.jsx(Bridge, {
236
+ children: /*#__PURE__*/jsxRuntime.jsx(events.ErrorBoundary, {
237
+ set: setError,
238
+ children: /*#__PURE__*/jsxRuntime.jsx(React__namespace.Suspense, {
239
+ fallback: /*#__PURE__*/jsxRuntime.jsx(events.Block, {
240
+ set: setBlock
241
+ }),
242
+ children: children
243
+ })
244
+ })
245
+ }));
234
246
  }
235
- });
236
- root.current.render( /*#__PURE__*/jsxRuntime.jsx(Bridge, {
237
- children: /*#__PURE__*/jsxRuntime.jsx(events.ErrorBoundary, {
238
- set: setError,
239
- children: /*#__PURE__*/jsxRuntime.jsx(React__namespace.Suspense, {
240
- fallback: /*#__PURE__*/jsxRuntime.jsx(events.Block, {
241
- set: setBlock
242
- }),
243
- children: children
244
- })
245
- })
246
- }));
247
- }
247
+ run();
248
+ }
249
+ });
248
250
  React__namespace.useEffect(() => {
249
251
  if (canvas) {
250
252
  return () => events.unmountComponentAtNode(canvas);
@@ -265,20 +267,19 @@ const CanvasImpl = /*#__PURE__*/React__namespace.forwardRef(({
265
267
  style: reactNative.StyleSheet.absoluteFill
266
268
  })
267
269
  });
268
- });
270
+ }
269
271
 
270
272
  /**
271
273
  * A native canvas which accepts threejs elements as children.
272
274
  * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
273
275
  */
274
- const Canvas = /*#__PURE__*/React__namespace.forwardRef(function CanvasWrapper(props, ref) {
276
+ function Canvas(props) {
275
277
  return /*#__PURE__*/jsxRuntime.jsx(itsFine.FiberProvider, {
276
278
  children: /*#__PURE__*/jsxRuntime.jsx(CanvasImpl, {
277
- ...props,
278
- ref: ref
279
+ ...props
279
280
  })
280
281
  });
281
- });
282
+ }
282
283
 
283
284
  /** Default R3F event manager for react-native */
284
285
  function createTouchEvents(store) {
@@ -542,7 +543,6 @@ exports.flushGlobalEffects = events.flushGlobalEffects;
542
543
  exports.getRootState = events.getRootState;
543
544
  exports.invalidate = events.invalidate;
544
545
  exports.reconciler = events.reconciler;
545
- exports.render = events.render;
546
546
  exports.unmountComponentAtNode = events.unmountComponentAtNode;
547
547
  exports.useFrame = events.useFrame;
548
548
  exports.useGraph = events.useGraph;