@react-three/fiber 8.0.0-beta-02 → 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.
@@ -1,19 +1,18 @@
1
- import { c as createEvents, q as buildGraph, r as is, a as createLoop, b as createRenderer, e as createStore, f as context, g as dispose, i as isRenderer } from '../../dist/hooks-c89a6f88.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, o as useGraph, u as useStore, m as useThree } from '../../dist/hooks-c89a6f88.esm.js';
3
- import * as THREE from 'three';
1
+ import { c as createEvents, s as buildGraph, v as is, a as createLoop, b as createRenderer, e as createStore, f as context, g as dispose, i as isRenderer, h as extend, p as pick, o as omit } from '../../dist/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, u as useStore, m as useThree } from '../../dist/hooks-15c12e3e.esm.js';
3
+ import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
+ import * as THREE from 'three';
6
+ import { PixelRatio, View, StyleSheet } from 'react-native';
7
+ import { GLView } from 'expo-gl';
5
8
  import { DefaultEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
6
9
  import Pressability from 'react-native/Libraries/Pressability/Pressability';
7
- import { View, StyleSheet, PixelRatio } from 'react-native';
8
10
  import { Asset } from 'expo-asset';
9
11
  import { readAsStringAsync } from 'expo-file-system';
10
12
  import { decode } from 'base64-arraybuffer';
11
13
  import { suspend, preload, clear } from 'suspend-react';
12
- import _extends from '@babel/runtime/helpers/esm/extends';
13
- import { GLView } from 'expo-gl';
14
- import pick from 'lodash-es/pick';
15
- import omit from 'lodash-es/omit';
16
14
  import 'react-reconciler';
15
+ import 'scheduler';
17
16
  import 'zustand';
18
17
 
19
18
  // @ts-ignore
@@ -109,127 +108,6 @@ function createTouchEvents(store) {
109
108
  };
110
109
  }
111
110
 
112
- const CANVAS_PROPS = ['gl', 'events', 'size', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', // 'dpr',
113
- 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated']; // React currently throws a warning when using useLayoutEffect on the server.
114
- // To get around it, we can conditionally useEffect on the server (no-op) and
115
- // useLayoutEffect in the browser.
116
-
117
- const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
118
-
119
- function Block({
120
- set
121
- }) {
122
- useIsomorphicLayoutEffect(() => {
123
- set(new Promise(() => null));
124
- return () => set(false);
125
- }, []);
126
- return null;
127
- }
128
-
129
- class ErrorBoundary extends React.Component {
130
- constructor(...args) {
131
- super(...args);
132
- this.state = {
133
- error: false
134
- };
135
- }
136
-
137
- componentDidCatch(error) {
138
- this.props.set(error);
139
- }
140
-
141
- render() {
142
- return this.state.error ? null : this.props.children;
143
- }
144
-
145
- }
146
-
147
- ErrorBoundary.getDerivedStateFromError = () => ({
148
- error: true
149
- });
150
-
151
- const Canvas = /*#__PURE__*/React.forwardRef(({
152
- children,
153
- fallback,
154
- style,
155
- events,
156
- nativeRef_EXPERIMENTAL,
157
- onContextCreate,
158
- ...props
159
- }, forwardedRef) => {
160
- const canvasProps = pick(props, CANVAS_PROPS);
161
- const viewProps = omit(props, CANVAS_PROPS);
162
- const [context, setContext] = React.useState(null);
163
- const [{
164
- width,
165
- height
166
- }, setSize] = React.useState({
167
- width: 0,
168
- height: 0
169
- });
170
- const [bind, setBind] = React.useState();
171
- const [block, setBlock] = React.useState(false);
172
- const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
173
-
174
- if (block) throw block; // Throw exception outwards if anything within canvas throws
175
-
176
- if (error) throw error;
177
- const onLayout = React.useCallback(e => {
178
- const {
179
- width,
180
- height
181
- } = e.nativeEvent.layout;
182
- setSize({
183
- width,
184
- height
185
- });
186
- }, []); // Execute JSX in the reconciler as a layout-effect
187
-
188
- useIsomorphicLayoutEffect(() => {
189
- if (width > 0 && height > 0 && context) {
190
- const store = render( /*#__PURE__*/React.createElement(ErrorBoundary, {
191
- set: setError
192
- }, /*#__PURE__*/React.createElement(React.Suspense, {
193
- fallback: /*#__PURE__*/React.createElement(Block, {
194
- set: setBlock
195
- })
196
- }, children)), context, { ...canvasProps,
197
- size: {
198
- width,
199
- height
200
- },
201
- events: events || createTouchEvents
202
- });
203
- const state = store.getState();
204
- setBind(state.events.connected.getEventHandlers());
205
- }
206
- }, [width, height, children, context, canvasProps]);
207
- useIsomorphicLayoutEffect(() => {
208
- return () => {
209
- if (context) unmountComponentAtNode(context);
210
- };
211
- }, []);
212
- return /*#__PURE__*/React.createElement(View, _extends({}, viewProps, {
213
- ref: forwardedRef,
214
- onLayout: onLayout,
215
- style: {
216
- flex: 1,
217
- ...style
218
- }
219
- }, bind), width > 0 && /*#__PURE__*/React.createElement(GLView, {
220
- nativeRef_EXPERIMENTAL: ref => {
221
- if (nativeRef_EXPERIMENTAL && !nativeRef_EXPERIMENTAL.current) {
222
- nativeRef_EXPERIMENTAL.current = ref;
223
- }
224
- },
225
- onContextCreate: async gl => {
226
- await (onContextCreate == null ? void 0 : onContextCreate(gl));
227
- setContext(gl);
228
- },
229
- style: StyleSheet.absoluteFill
230
- }));
231
- });
232
-
233
111
  /**
234
112
  * Generates an asset based on input type.
235
113
  */
@@ -264,8 +142,6 @@ function loadingFn(extensions, onProgress) {
264
142
  if (extensions) extensions(loader); // Go through the urls and load them
265
143
 
266
144
  return Promise.all(input.map(entry => new Promise(async (res, reject) => {
267
- var _parse, _ref;
268
-
269
145
  // Construct URL
270
146
  const url = typeof entry === 'string' ? loader.path + entry : entry; // There's no Image in native, so we create & pass a data texture instead
271
147
 
@@ -312,7 +188,7 @@ function loadingFn(extensions, onProgress) {
312
188
  } = await getAsset(url).downloadAsync();
313
189
  const arrayBuffer = await toBuffer(localUri); // Parse it
314
190
 
315
- const parsed = (_parse = (_ref = loader).parse) == null ? void 0 : _parse.call(_ref, arrayBuffer, undefined, data => {
191
+ const parsed = loader.parse == null ? void 0 : loader.parse(arrayBuffer, undefined, data => {
316
192
  if (data.scene) Object.assign(data, buildGraph(data.scene));
317
193
  res(data);
318
194
  }, error => reject(`Could not load ${url}: ${error.message}`)); // Respect synchronous parsers which don't have callbacks
@@ -394,84 +270,90 @@ const createRendererInstance = (gl, context) => {
394
270
 
395
271
  function createRoot(context, config) {
396
272
  return {
397
- render: element => render(element, context, config),
273
+ render: element => {
274
+ var _store;
275
+
276
+ let {
277
+ gl,
278
+ size = {
279
+ width: 0,
280
+ height: 0
281
+ },
282
+ events,
283
+ onCreated,
284
+ ...props
285
+ } = config || {};
286
+ let root = roots.get(context);
287
+ let fiber = root == null ? void 0 : root.fiber;
288
+ let store = root == null ? void 0 : root.store;
289
+ let state = (_store = store) == null ? void 0 : _store.getState();
290
+
291
+ if (fiber && state) {
292
+ // When a root was found, see if any fundamental props must be changed or exchanged
293
+ // Check size
294
+ if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // Check frameloop
295
+
296
+ if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
297
+ // Changes to the color-space
298
+
299
+ const linearChanged = props.linear !== state.internal.lastProps.linear;
300
+
301
+ if (linearChanged) {
302
+ unmountComponentAtNode(context);
303
+ fiber = undefined;
304
+ }
305
+ }
306
+
307
+ if (!fiber) {
308
+ // If no root has been found, make one
309
+ // Create gl
310
+ const glRenderer = createRendererInstance(gl, context); // Create store
311
+
312
+ store = createStore(applyProps, invalidate, advance, {
313
+ gl: glRenderer,
314
+ size,
315
+ ...props,
316
+ // expo-gl can only render at native dpr/resolution
317
+ // https://github.com/expo/expo-three/issues/39
318
+ dpr: PixelRatio.get()
319
+ });
320
+ const state = store.getState(); // Create renderer
321
+
322
+ fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
323
+
324
+ roots.set(context, {
325
+ fiber,
326
+ store
327
+ }); // Store event manager internally and connect it
328
+
329
+ if (events) {
330
+ var _state$get$events$con, _state$get$events;
331
+
332
+ state.set({
333
+ events: events(store)
334
+ });
335
+ (_state$get$events$con = (_state$get$events = state.get().events).connect) == null ? void 0 : _state$get$events$con.call(_state$get$events, context);
336
+ }
337
+ }
338
+
339
+ if (store && fiber) {
340
+ reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
341
+ store: store,
342
+ element: element,
343
+ onCreated: onCreated
344
+ }), fiber, null, () => undefined);
345
+ return store;
346
+ } else {
347
+ throw 'Error creating root!';
348
+ }
349
+ },
398
350
  unmount: () => unmountComponentAtNode(context)
399
351
  };
400
352
  }
401
353
 
402
- function render(element, context, {
403
- gl,
404
- size = {
405
- width: 0,
406
- height: 0
407
- },
408
- events,
409
- onCreated,
410
- ...props
411
- } = {}) {
412
- var _store;
413
-
414
- let root = roots.get(context);
415
- let fiber = root == null ? void 0 : root.fiber;
416
- let store = root == null ? void 0 : root.store;
417
- let state = (_store = store) == null ? void 0 : _store.getState();
418
-
419
- if (fiber && state) {
420
- // When a root was found, see if any fundamental props must be changed or exchanged
421
- // Check size
422
- if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // For some props we want to reset the entire root
423
- // Changes to the color-space
424
-
425
- const linearChanged = props.linear !== state.internal.lastProps.linear;
426
-
427
- if (linearChanged) {
428
- unmountComponentAtNode(context);
429
- fiber = undefined;
430
- }
431
- }
432
-
433
- if (!fiber) {
434
- // If no root has been found, make one
435
- // Create gl
436
- const glRenderer = createRendererInstance(gl, context); // Create store
437
-
438
- store = createStore(applyProps, invalidate, advance, {
439
- gl: glRenderer,
440
- size,
441
- ...props,
442
- // expo-gl can only render at native dpr/resolution
443
- // https://github.com/expo/expo-three/issues/39
444
- dpr: PixelRatio.get()
445
- });
446
- const state = store.getState(); // Create renderer
447
-
448
- fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
449
-
450
- roots.set(context, {
451
- fiber,
452
- store
453
- }); // Store event manager internally and connect it
454
-
455
- if (events) {
456
- var _state$get$events$con, _state$get$events;
457
-
458
- state.set({
459
- events: events(store)
460
- });
461
- (_state$get$events$con = (_state$get$events = state.get().events).connect) == null ? void 0 : _state$get$events$con.call(_state$get$events, context);
462
- }
463
- }
464
-
465
- if (store && fiber) {
466
- reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
467
- store: store,
468
- element: element,
469
- onCreated: onCreated
470
- }), fiber, null, () => undefined);
471
- return store;
472
- } else {
473
- throw 'Error creating root!';
474
- }
354
+ function render(element, context, config = {}) {
355
+ console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
356
+ return createRoot(context, config).render(element);
475
357
  }
476
358
 
477
359
  function Provider({
@@ -523,7 +405,7 @@ function unmountComponentAtNode(context, callback) {
523
405
  }
524
406
  }
525
407
 
526
- const act = reconciler.act;
408
+ const act = React.unstable_act;
527
409
 
528
410
  function createPortal(children, container) {
529
411
  return reconciler.createPortal(children, container, null, null);
@@ -535,4 +417,121 @@ reconciler.injectIntoDevTools({
535
417
  version: '18.0.0'
536
418
  });
537
419
 
420
+ const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
421
+
422
+ function Block({
423
+ set
424
+ }) {
425
+ React.useLayoutEffect(() => {
426
+ set(new Promise(() => null));
427
+ return () => set(false);
428
+ }, [set]);
429
+ return null;
430
+ }
431
+
432
+ class ErrorBoundary extends React.Component {
433
+ constructor(...args) {
434
+ super(...args);
435
+ this.state = {
436
+ error: false
437
+ };
438
+ }
439
+
440
+ componentDidCatch(error) {
441
+ this.props.set(error);
442
+ }
443
+
444
+ render() {
445
+ return this.state.error ? null : this.props.children;
446
+ }
447
+
448
+ }
449
+
450
+ ErrorBoundary.getDerivedStateFromError = () => ({
451
+ error: true
452
+ });
453
+
454
+ const Canvas = /*#__PURE__*/React.forwardRef(({
455
+ children,
456
+ fallback,
457
+ style,
458
+ events,
459
+ nativeRef_EXPERIMENTAL,
460
+ onContextCreate,
461
+ ...props
462
+ }, forwardedRef) => {
463
+ // Create a known catalogue of Threejs-native elements
464
+ // This will include the entire THREE namespace by default, users can extend
465
+ // their own elements by using the createRoot API instead
466
+ React.useMemo(() => extend(THREE), []);
467
+ const [{
468
+ width,
469
+ height
470
+ }, setSize] = React.useState({
471
+ width: 0,
472
+ height: 0
473
+ });
474
+ const [context, setContext] = React.useState(null);
475
+ const [bind, setBind] = React.useState();
476
+ const canvasProps = pick(props, CANVAS_PROPS);
477
+ const viewProps = omit(props, CANVAS_PROPS);
478
+ const [block, setBlock] = React.useState(false);
479
+ const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
480
+
481
+ if (block) throw block; // Throw exception outwards if anything within canvas throws
482
+
483
+ if (error) throw error;
484
+ const onLayout = React.useCallback(e => {
485
+ const {
486
+ width,
487
+ height
488
+ } = e.nativeEvent.layout;
489
+ setSize({
490
+ width,
491
+ height
492
+ });
493
+ }, []);
494
+
495
+ if (width > 0 && height > 0 && context) {
496
+ const store = createRoot(context, { ...canvasProps,
497
+ size: {
498
+ width,
499
+ height
500
+ },
501
+ events: events || createTouchEvents
502
+ }).render( /*#__PURE__*/React.createElement(ErrorBoundary, {
503
+ set: setError
504
+ }, /*#__PURE__*/React.createElement(React.Suspense, {
505
+ fallback: /*#__PURE__*/React.createElement(Block, {
506
+ set: setBlock
507
+ })
508
+ }, children)));
509
+ const state = store.getState();
510
+ setBind(state.events.connected.getEventHandlers());
511
+ }
512
+
513
+ React.useEffect(() => {
514
+ return () => unmountComponentAtNode(context);
515
+ }, [context]);
516
+ return /*#__PURE__*/React.createElement(View, _extends({}, viewProps, {
517
+ ref: forwardedRef,
518
+ onLayout: onLayout,
519
+ style: {
520
+ flex: 1,
521
+ ...style
522
+ }
523
+ }, bind), width > 0 && /*#__PURE__*/React.createElement(GLView, {
524
+ nativeRef_EXPERIMENTAL: ref => {
525
+ if (nativeRef_EXPERIMENTAL && !nativeRef_EXPERIMENTAL.current) {
526
+ nativeRef_EXPERIMENTAL.current = ref;
527
+ }
528
+ },
529
+ onContextCreate: async gl => {
530
+ await (onContextCreate == null ? void 0 : onContextCreate(gl));
531
+ setContext(gl);
532
+ },
533
+ style: StyleSheet.absoluteFill
534
+ }));
535
+ });
536
+
538
537
  export { Canvas, roots as _roots, act, advance, applyProps, createPortal, createRoot, createTouchEvents as events, invalidate, reconciler, render, unmountComponentAtNode, useLoader };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/fiber",
3
- "version": "8.0.0-beta-02",
3
+ "version": "8.0.0-beta-03",
4
4
  "description": "A React renderer for Threejs",
5
5
  "keywords": [
6
6
  "react",
@@ -12,7 +12,8 @@
12
12
  "author": "Paul Henschel (https://github.com/drcmda)",
13
13
  "license": "MIT",
14
14
  "maintainers": [
15
- "Josh Ellis (https://github.com/joshuaellis)"
15
+ "Josh Ellis (https://github.com/joshuaellis)",
16
+ "Cody Bennett (https://github.com/codyjasonbennett)"
16
17
  ],
17
18
  "bugs": {
18
19
  "url": "https://github.com/pmndrs/react-three-fiber/issues"
@@ -46,13 +47,11 @@
46
47
  "expo-asset": "^8.4.3",
47
48
  "expo-file-system": "^13.0.3",
48
49
  "expo-gl": "^11.0.3",
49
- "lodash": "^4.17.21",
50
- "lodash-es": "^4.17.21",
51
50
  "react-merge-refs": "^1.1.0",
52
- "react-reconciler": "^0.27.0-beta-96ca8d915-20211115",
53
- "react-use-measure": "^2.0.4",
51
+ "react-reconciler": "^0.27.0-rc.0",
52
+ "react-use-measure": "^2.1.1",
54
53
  "resize-observer-polyfill": "^1.5.1",
55
- "scheduler": "0.0.0-experimental-031abd24b-20210907",
54
+ "scheduler": "0.21.0-rc.0",
56
55
  "suspend-react": "^0.0.8",
57
56
  "utility-types": "^3.10.0",
58
57
  "zustand": "^3.5.10"
@@ -60,7 +59,7 @@
60
59
  "peerDependencies": {
61
60
  "react": ">=18.0",
62
61
  "react-dom": ">=18.0",
63
- "react-native": "^>=0.64",
62
+ "react-native": ">=0.64",
64
63
  "three": ">=0.132"
65
64
  },
66
65
  "peerDependenciesMeta": {
package/readme.md CHANGED
@@ -156,7 +156,7 @@ ReactDOM.render(
156
156
  You need to be versed in both React and Threejs before rushing into this. If you are unsure about React consult the official [React docs](https://reactjs.org/docs/getting-started.html), especially [the section about hooks](https://reactjs.org/docs/hooks-reference.html). As for Threejs, make sure you at least glance over the following links:
157
157
 
158
158
  1. Make sure you have a [basic grasp of Threejs](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene). Keep that site open.
159
- 2. When you know what a scene is, a camera, mesh, geometry, material, fork the [demo above](https://github.com/react-spring/react-three-fiber#what-does-it-look-like).
159
+ 2. When you know what a scene is, a camera, mesh, geometry, material, fork the [demo above](https://github.com/pmndrs/react-three-fiber#what-does-it-look-like).
160
160
  3. [Look up](https://threejs.org/docs/index.html#api/en/objects/Mesh) the JSX elements that you see (mesh, ambientLight, etc), _all_ threejs exports are native to three-fiber.
161
161
  4. Try changing some values, scroll though our [Api](/markdown/api.md) to see what the various settings and hooks do.
162
162
 
@@ -171,15 +171,15 @@ Some reading material:
171
171
 
172
172
  # Ecosystem
173
173
 
174
- - [`@react-three/gltfjsx`](https://github.com/react-spring/gltfjsx) – turns GLTFs into JSX components
175
- - [`@react-three/drei`](https://github.com/react-spring/drei) – useful helpers for react-three-fiber
176
- - [`@react-three/postprocessing`](https://github.com/react-spring/react-postprocessing) – post-processing effects
177
- - [`@react-three/flex`](https://github.com/react-spring/react-three-flex) – flexbox for react-three-fiber
178
- - [`@react-three/xr`](https://github.com/react-spring/react-xr) – VR/AR controllers and events
179
- - [`@react-three/cannon`](https://github.com/react-spring/use-cannon) – physics based hooks
180
- - [`zustand`](https://github.com/react-spring/zustand) – state management
181
- - [`react-spring`](https://github.com/react-spring/react-spring) – a spring-physics-based animation library
182
- - [`react-use-gesture`](https://github.com/react-spring/react-use-gesture) – mouse/touch gestures
174
+ - [`@react-three/gltfjsx`](https://github.com/pmndrs/gltfjsx) – turns GLTFs into JSX components
175
+ - [`@react-three/drei`](https://github.com/pmndrs/drei) – useful helpers for react-three-fiber
176
+ - [`@react-three/postprocessing`](https://github.com/pmndrs/react-postprocessing) – post-processing effects
177
+ - [`@react-three/flex`](https://github.com/pmndrs/react-three-flex) – flexbox for react-three-fiber
178
+ - [`@react-three/xr`](https://github.com/pmndrs/react-xr) – VR/AR controllers and events
179
+ - [`@react-three/cannon`](https://github.com/pmndrs/use-cannon) – physics based hooks
180
+ - [`zustand`](https://github.com/pmndrs/zustand) – state management
181
+ - [`react-spring`](https://github.com/pmndrs/react-spring) – a spring-physics-based animation library
182
+ - [`react-use-gesture`](https://github.com/pmndrs/react-use-gesture) – mouse/touch gestures
183
183
 
184
184
  # How to contribute
185
185