@react-three/fiber 8.0.0-beta-02 → 8.0.0-beta.0

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,77 +1,35 @@
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 } from './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, p as useLoader, u as useStore, m as useThree } from './hooks-c89a6f88.esm.js';
3
- import * as THREE from 'three';
4
- import * as React from 'react';
5
- import { DefaultEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
1
+ import { c as createEvents, e as extend, p as pick, o as omit, a as createRoot, u as unmountComponentAtNode } from './index-3f4e5f46.esm.js';
2
+ export { t as ReactThreeFiber, q as _roots, n as act, l as addAfterEffect, k as addEffect, m as addTail, j as advance, g as applyProps, b as context, d as createPortal, a as createRoot, h as dispose, e as extend, i as invalidate, f as reconciler, r as render, u as unmountComponentAtNode, w as useFrame, x as useGraph, y as useLoader, s as useStore, v as useThree } from './index-3f4e5f46.esm.js';
6
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
+ import * as React from 'react';
5
+ import * as THREE from 'three';
7
6
  import mergeRefs from 'react-merge-refs';
8
7
  import useMeasure from 'react-use-measure';
9
- import pick from 'lodash-es/pick';
10
- import omit from 'lodash-es/omit';
11
- import 'react-reconciler';
12
8
  import 'suspend-react';
9
+ import 'react-reconciler/constants';
13
10
  import 'zustand';
14
-
15
- // @ts-ignore
16
- const CLICK = 'click';
17
- const CONTEXTMENU = 'contextmenu';
18
- const DBLCLICK = 'dblclick';
19
- const POINTERCANCEL = 'pointercancel';
20
- const POINTERDOWN = 'pointerdown';
21
- const POINTERUP = 'pointerup';
22
- const POINTERMOVE = 'pointermove';
23
- const POINTEROUT = 'pointerout';
24
- const POINTEROVER = 'pointerover';
25
- const POINTERENTER = 'pointerenter';
26
- const POINTERLEAVE = 'pointerleave';
27
- const WHEEL = 'wheel'; // https://github.com/facebook/react/tree/main/packages/react-reconciler#getcurrenteventpriority
28
- // Gives React a clue as to how import the current interaction is
29
-
30
- function getEventPriority() {
31
- var _window, _window$event;
32
-
33
- let name = (_window = window) == null ? void 0 : (_window$event = _window.event) == null ? void 0 : _window$event.type;
34
-
35
- switch (name) {
36
- case CLICK:
37
- case CONTEXTMENU:
38
- case DBLCLICK:
39
- case POINTERCANCEL:
40
- case POINTERDOWN:
41
- case POINTERUP:
42
- return DiscreteEventPriority;
43
-
44
- case POINTERMOVE:
45
- case POINTEROUT:
46
- case POINTEROVER:
47
- case POINTERENTER:
48
- case POINTERLEAVE:
49
- case WHEEL:
50
- return ContinuousEventPriority;
51
-
52
- default:
53
- return DefaultEventPriority;
54
- }
55
- }
11
+ import 'react-reconciler';
12
+ import 'scheduler';
13
+
14
+ const DOM_EVENTS = {
15
+ onClick: ['click', false],
16
+ onContextMenu: ['contextmenu', false],
17
+ onDoubleClick: ['dblclick', false],
18
+ onWheel: ['wheel', true],
19
+ onPointerDown: ['pointerdown', true],
20
+ onPointerUp: ['pointerup', true],
21
+ onPointerLeave: ['pointerleave', true],
22
+ onPointerMove: ['pointermove', true],
23
+ onPointerCancel: ['pointercancel', true],
24
+ onLostPointerCapture: ['lostpointercapture', true]
25
+ };
56
26
  function createPointerEvents(store) {
57
27
  const {
58
28
  handlePointer
59
29
  } = createEvents(store);
60
- const names = {
61
- onClick: [CLICK, false],
62
- onContextMenu: [CONTEXTMENU, false],
63
- onDoubleClick: [DBLCLICK, false],
64
- onWheel: [WHEEL, true],
65
- onPointerDown: [POINTERDOWN, true],
66
- onPointerUp: [POINTERUP, true],
67
- onPointerLeave: [POINTERLEAVE, true],
68
- onPointerMove: [POINTERMOVE, true],
69
- onPointerCancel: [POINTERCANCEL, true],
70
- onLostPointerCapture: ['lostpointercapture', true]
71
- };
72
30
  return {
73
31
  connected: false,
74
- handlers: Object.keys(names).reduce((acc, key) => ({ ...acc,
32
+ handlers: Object.keys(DOM_EVENTS).reduce((acc, key) => ({ ...acc,
75
33
  [key]: handlePointer(key)
76
34
  }), {}),
77
35
  connect: target => {
@@ -88,7 +46,7 @@ function createPointerEvents(store) {
88
46
  }
89
47
  }));
90
48
  Object.entries((_events$handlers = events == null ? void 0 : events.handlers) != null ? _events$handlers : []).forEach(([name, event]) => {
91
- const [eventName, passive] = names[name];
49
+ const [eventName, passive] = DOM_EVENTS[name];
92
50
  target.addEventListener(eventName, event, {
93
51
  passive
94
52
  });
@@ -105,7 +63,7 @@ function createPointerEvents(store) {
105
63
 
106
64
  Object.entries((_events$handlers2 = events.handlers) != null ? _events$handlers2 : []).forEach(([name, event]) => {
107
65
  if (events && events.connected instanceof HTMLElement) {
108
- const [eventName] = names[name];
66
+ const [eventName] = DOM_EVENTS[name];
109
67
  events.connected.removeEventListener(eventName, event);
110
68
  }
111
69
  });
@@ -119,19 +77,15 @@ function createPointerEvents(store) {
119
77
  };
120
78
  }
121
79
 
122
- const CANVAS_PROPS = ['gl', 'events', 'size', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'dpr', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated']; // React currently throws a warning when using useLayoutEffect on the server.
123
- // To get around it, we can conditionally useEffect on the server (no-op) and
124
- // useLayoutEffect in the browser.
125
-
126
- const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
80
+ const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'dpr', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
127
81
 
128
82
  function Block({
129
83
  set
130
84
  }) {
131
- useIsomorphicLayoutEffect(() => {
85
+ React.useLayoutEffect(() => {
132
86
  set(new Promise(() => null));
133
87
  return () => set(false);
134
- }, []);
88
+ }, [set]);
135
89
  return null;
136
90
  }
137
91
 
@@ -165,8 +119,10 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
165
119
  events,
166
120
  ...props
167
121
  }, forwardedRef) {
168
- const canvasProps = pick(props, CANVAS_PROPS);
169
- const divProps = omit(props, CANVAS_PROPS);
122
+ // Create a known catalogue of Threejs-native elements
123
+ // This will include the entire THREE namespace by default, users can extend
124
+ // their own elements by using the createRoot API instead
125
+ React.useMemo(() => extend(THREE), []);
170
126
  const [containerRef, {
171
127
  width,
172
128
  height
@@ -179,34 +135,38 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
179
135
  ...resize
180
136
  });
181
137
  const canvasRef = React.useRef(null);
138
+ const [canvas, setCanvas] = React.useState(null);
139
+ const canvasProps = pick(props, CANVAS_PROPS);
140
+ const divProps = omit(props, CANVAS_PROPS);
182
141
  const [block, setBlock] = React.useState(false);
183
142
  const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
184
143
 
185
144
  if (block) throw block; // Throw exception outwards if anything within canvas throws
186
145
 
187
- if (error) throw error; // Execute JSX in the reconciler as a layout-effect
146
+ if (error) throw error;
147
+
148
+ if (width > 0 && height > 0 && canvas) {
149
+ createRoot(canvas, { ...canvasProps,
150
+ size: {
151
+ width,
152
+ height
153
+ },
154
+ events: events || createPointerEvents
155
+ }).render( /*#__PURE__*/React.createElement(ErrorBoundary, {
156
+ set: setError
157
+ }, /*#__PURE__*/React.createElement(React.Suspense, {
158
+ fallback: /*#__PURE__*/React.createElement(Block, {
159
+ set: setBlock
160
+ })
161
+ }, children)));
162
+ }
188
163
 
189
- useIsomorphicLayoutEffect(() => {
190
- if (width > 0 && height > 0) {
191
- render( /*#__PURE__*/React.createElement(ErrorBoundary, {
192
- set: setError
193
- }, /*#__PURE__*/React.createElement(React.Suspense, {
194
- fallback: /*#__PURE__*/React.createElement(Block, {
195
- set: setBlock
196
- })
197
- }, children)), canvasRef.current, { ...canvasProps,
198
- size: {
199
- width,
200
- height
201
- },
202
- events: events || createPointerEvents
203
- });
204
- }
205
- }, [width, height, children, canvasProps]);
206
- React.useEffect(() => {
207
- const container = canvasRef.current;
208
- return () => unmountComponentAtNode(container);
164
+ React.useLayoutEffect(() => {
165
+ setCanvas(canvasRef.current);
209
166
  }, []);
167
+ React.useEffect(() => {
168
+ return () => unmountComponentAtNode(canvas);
169
+ }, [canvas]);
210
170
  return /*#__PURE__*/React.createElement("div", _extends({
211
171
  ref: containerRef,
212
172
  style: {
@@ -224,181 +184,4 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
224
184
  }, fallback));
225
185
  });
226
186
 
227
- const roots = new Map();
228
- const {
229
- invalidate,
230
- advance
231
- } = createLoop(roots);
232
- const {
233
- reconciler,
234
- applyProps
235
- } = createRenderer(roots, getEventPriority);
236
-
237
- const createRendererInstance = (gl, canvas) => {
238
- const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
239
- if (isRenderer(customRenderer)) return customRenderer;
240
- const renderer = new THREE.WebGLRenderer({
241
- powerPreference: 'high-performance',
242
- canvas: canvas,
243
- antialias: true,
244
- alpha: true,
245
- ...gl
246
- }); // Set color management
247
-
248
- renderer.outputEncoding = THREE.sRGBEncoding;
249
- renderer.toneMapping = THREE.ACESFilmicToneMapping; // Set gl props
250
-
251
- if (gl) applyProps(renderer, gl);
252
- return renderer;
253
- };
254
-
255
- function createRoot(canvas, config) {
256
- return {
257
- render: element => render(element, canvas, config),
258
- unmount: () => unmountComponentAtNode(canvas)
259
- };
260
- }
261
-
262
- function render(element, canvas, {
263
- gl,
264
- size,
265
- events,
266
- onCreated,
267
- ...props
268
- } = {}) {
269
- var _store;
270
-
271
- // Allow size to take on container bounds initially
272
- if (!size) {
273
- var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
274
-
275
- size = {
276
- width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
277
- height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
278
- };
279
- }
280
-
281
- let root = roots.get(canvas);
282
- let fiber = root == null ? void 0 : root.fiber;
283
- let store = root == null ? void 0 : root.store;
284
- let state = (_store = store) == null ? void 0 : _store.getState();
285
-
286
- if (fiber && state) {
287
- // When a root was found, see if any fundamental props must be changed or exchanged
288
- // Check pixelratio
289
- if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
290
-
291
- 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
292
- // Changes to the color-space
293
-
294
- const linearChanged = props.linear !== state.internal.lastProps.linear;
295
-
296
- if (linearChanged) {
297
- unmountComponentAtNode(canvas);
298
- fiber = undefined;
299
- }
300
- }
301
-
302
- if (!fiber) {
303
- // If no root has been found, make one
304
- // Create gl
305
- const glRenderer = createRendererInstance(gl, canvas); // Create store
306
-
307
- store = createStore(applyProps, invalidate, advance, {
308
- gl: glRenderer,
309
- size,
310
- ...props
311
- });
312
- const state = store.getState(); // Create renderer
313
-
314
- fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
315
-
316
- roots.set(canvas, {
317
- fiber,
318
- store
319
- }); // Store events internally
320
-
321
- if (events) state.set({
322
- events: events(store)
323
- });
324
- }
325
-
326
- if (store && fiber) {
327
- reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
328
- store: store,
329
- element: element,
330
- onCreated: onCreated,
331
- target: canvas
332
- }), fiber, null, () => undefined);
333
- return store;
334
- } else {
335
- throw 'Error creating root!';
336
- }
337
- }
338
-
339
- function Provider({
340
- store,
341
- element,
342
- onCreated,
343
- target
344
- }) {
345
- React.useEffect(() => {
346
- const state = store.getState(); // Flag the canvas active, rendering will now begin
347
-
348
- state.set(state => ({
349
- internal: { ...state.internal,
350
- active: true
351
- }
352
- })); // Connect events
353
-
354
- state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
355
-
356
- if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
357
- }, []);
358
- return /*#__PURE__*/React.createElement(context.Provider, {
359
- value: store
360
- }, element);
361
- }
362
-
363
- function unmountComponentAtNode(canvas, callback) {
364
- const root = roots.get(canvas);
365
- const fiber = root == null ? void 0 : root.fiber;
366
-
367
- if (fiber) {
368
- const state = root == null ? void 0 : root.store.getState();
369
- if (state) state.internal.active = false;
370
- reconciler.updateContainer(null, fiber, null, () => {
371
- if (state) {
372
- setTimeout(() => {
373
- try {
374
- var _state$gl, _state$gl$renderLists, _state$gl2, _state$gl3;
375
-
376
- state.events.disconnect == null ? void 0 : state.events.disconnect();
377
- (_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();
378
- (_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
379
- if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.internal.xr.disconnect();
380
- dispose(state);
381
- roots.delete(canvas);
382
- if (callback) callback(canvas);
383
- } catch (e) {
384
- /* ... */
385
- }
386
- }, 500);
387
- }
388
- });
389
- }
390
- }
391
-
392
- const act = reconciler.act;
393
-
394
- function createPortal(children, container) {
395
- return reconciler.createPortal(children, container, null, null);
396
- }
397
-
398
- reconciler.injectIntoDevTools({
399
- bundleType: process.env.NODE_ENV === 'production' ? 0 : 1,
400
- rendererPackageName: '@react-three/fiber',
401
- version: '18.0.0'
402
- });
403
-
404
- export { Canvas, roots as _roots, act, advance, applyProps, createPortal, createRoot, createPointerEvents as events, invalidate, reconciler, render, unmountComponentAtNode };
187
+ export { Canvas, createPointerEvents as events };