@react-three/fiber 9.5.0 → 10.0.0-alpha.1

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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.cjs +15250 -0
  3. package/dist/index.d.cts +3526 -0
  4. package/dist/index.d.mts +3526 -0
  5. package/dist/index.d.ts +3526 -0
  6. package/dist/index.mjs +15163 -0
  7. package/dist/{events-358c3764.cjs.dev.js → legacy.cjs} +5751 -6761
  8. package/dist/legacy.d.cts +3525 -0
  9. package/dist/legacy.d.mts +3525 -0
  10. package/dist/legacy.d.ts +3525 -0
  11. package/dist/{events-5a94e5eb.esm.js → legacy.mjs} +5700 -6739
  12. package/dist/webgpu/index.cjs +15715 -0
  13. package/dist/webgpu/index.d.cts +3678 -0
  14. package/dist/webgpu/index.d.mts +3678 -0
  15. package/dist/webgpu/index.d.ts +3678 -0
  16. package/dist/webgpu/index.mjs +15616 -0
  17. package/package.json +43 -45
  18. package/readme.md +98 -33
  19. package/CHANGELOG.md +0 -1192
  20. package/dist/declarations/react-reconciler/index.d.ts +0 -1044
  21. package/dist/declarations/src/core/events.d.ts +0 -92
  22. package/dist/declarations/src/core/hooks.d.ts +0 -53
  23. package/dist/declarations/src/core/index.d.ts +0 -13
  24. package/dist/declarations/src/core/loop.d.ts +0 -31
  25. package/dist/declarations/src/core/reconciler.d.ts +0 -50
  26. package/dist/declarations/src/core/renderer.d.ts +0 -89
  27. package/dist/declarations/src/core/store.d.ts +0 -130
  28. package/dist/declarations/src/core/utils.d.ts +0 -262
  29. package/dist/declarations/src/index.d.ts +0 -6
  30. package/dist/declarations/src/native/Canvas.d.ts +0 -13
  31. package/dist/declarations/src/native/events.d.ts +0 -4
  32. package/dist/declarations/src/native.d.ts +0 -6
  33. package/dist/declarations/src/three-types.d.ts +0 -68
  34. package/dist/declarations/src/web/Canvas.d.ts +0 -23
  35. package/dist/declarations/src/web/events.d.ts +0 -4
  36. package/dist/events-238e0986.cjs.prod.js +0 -8048
  37. package/dist/react-three-fiber.cjs.d.ts +0 -2
  38. package/dist/react-three-fiber.cjs.dev.js +0 -220
  39. package/dist/react-three-fiber.cjs.js +0 -7
  40. package/dist/react-three-fiber.cjs.prod.js +0 -220
  41. package/dist/react-three-fiber.esm.js +0 -165
  42. package/native/dist/react-three-fiber-native.cjs.d.ts +0 -2
  43. package/native/dist/react-three-fiber-native.cjs.dev.js +0 -567
  44. package/native/dist/react-three-fiber-native.cjs.js +0 -7
  45. package/native/dist/react-three-fiber-native.cjs.prod.js +0 -567
  46. package/native/dist/react-three-fiber-native.esm.js +0 -515
  47. package/native/package.json +0 -5
@@ -1,515 +0,0 @@
1
- import { e as extend, u as useBridge, a as useMutableCallback, c as createRoot, b as useIsomorphicLayoutEffect, E as ErrorBoundary, B as Block, d as unmountComponentAtNode, f as createPointerEvents, g as createEvents } from '../../dist/events-5a94e5eb.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, o as createPortal, c as createRoot, w as dispose, e as extend, h as flushGlobalEffects, p as flushSync, v as getRootState, m as invalidate, r as reconciler, d as unmountComponentAtNode, D as useFrame, F as useGraph, z as useInstanceHandle, G as useLoader, A as useStore, C as useThree } from '../../dist/events-5a94e5eb.esm.js';
3
- import * as React from 'react';
4
- import * as THREE from 'three';
5
- import { PanResponder, PixelRatio, StyleSheet, View, Platform, Image, NativeModules } from 'react-native';
6
- import { GLView } from 'expo-gl';
7
- import { FiberProvider } from 'its-fine';
8
- import { jsx, jsxs } from 'react/jsx-runtime';
9
- import { Asset } from 'expo-asset';
10
- import { fromByteArray } from 'base64-js';
11
- import { Buffer } from 'buffer';
12
- import 'zustand/traditional';
13
- import 'suspend-react';
14
- import 'scheduler';
15
-
16
- // TODO: React 19 needs support from react-native
17
- const _View = View;
18
- function CanvasImpl({
19
- children,
20
- style,
21
- gl,
22
- events = createPointerEvents,
23
- shadows,
24
- linear,
25
- flat,
26
- legacy,
27
- orthographic,
28
- frameloop,
29
- performance,
30
- raycaster,
31
- camera,
32
- scene,
33
- onPointerMissed,
34
- onCreated,
35
- ref,
36
- pointerEvents,
37
- ...props
38
- }) {
39
- // Create a known catalogue of Threejs-native elements
40
- // This will include the entire THREE namespace by default, users can extend
41
- // their own elements by using the createRoot API instead
42
- React.useMemo(() => extend(THREE), []);
43
- const Bridge = useBridge();
44
- const [{
45
- width,
46
- height,
47
- top,
48
- left
49
- }, setSize] = React.useState({
50
- width: 0,
51
- height: 0,
52
- top: 0,
53
- left: 0
54
- });
55
- const [canvas, setCanvas] = React.useState(null);
56
- const [bind, setBind] = React.useState();
57
- React.useImperativeHandle(ref, () => viewRef.current);
58
- const handlePointerMissed = useMutableCallback(onPointerMissed);
59
- const [block, setBlock] = React.useState(false);
60
- const [error, setError] = React.useState(undefined);
61
-
62
- // Suspend this component if block is a promise (2nd run)
63
- if (block) throw block;
64
- // Throw exception outwards if anything within canvas throws
65
- if (error) throw error;
66
- const viewRef = React.useRef(null);
67
- const root = React.useRef(null);
68
- const [antialias, setAntialias] = React.useState(true);
69
- const onLayout = React.useCallback(e => {
70
- const {
71
- width,
72
- height,
73
- x,
74
- y
75
- } = e.nativeEvent.layout;
76
- setSize({
77
- width,
78
- height,
79
- top: y,
80
- left: x
81
- });
82
- }, []);
83
-
84
- // Called on context create or swap
85
- // https://github.com/pmndrs/react-three-fiber/pull/2297
86
- const onContextCreate = React.useCallback(context => {
87
- const listeners = new Map();
88
- const canvas = {
89
- style: {},
90
- width: context.drawingBufferWidth,
91
- height: context.drawingBufferHeight,
92
- clientWidth: context.drawingBufferWidth,
93
- clientHeight: context.drawingBufferHeight,
94
- getContext: (_, {
95
- antialias = false
96
- }) => {
97
- setAntialias(antialias);
98
- return context;
99
- },
100
- addEventListener(type, listener) {
101
- let callbacks = listeners.get(type);
102
- if (!callbacks) {
103
- callbacks = [];
104
- listeners.set(type, callbacks);
105
- }
106
- callbacks.push(listener);
107
- },
108
- removeEventListener(type, listener) {
109
- const callbacks = listeners.get(type);
110
- if (callbacks) {
111
- const index = callbacks.indexOf(listener);
112
- if (index !== -1) callbacks.splice(index, 1);
113
- }
114
- },
115
- dispatchEvent(event) {
116
- Object.assign(event, {
117
- target: this
118
- });
119
- const callbacks = listeners.get(event.type);
120
- if (callbacks) {
121
- for (const callback of callbacks) {
122
- callback(event);
123
- }
124
- }
125
- },
126
- setPointerCapture() {
127
- // TODO
128
- },
129
- releasePointerCapture() {
130
- // TODO
131
- }
132
- };
133
-
134
- // TODO: this is wrong but necessary to trick controls
135
- // @ts-ignore
136
- canvas.ownerDocument = canvas;
137
- canvas.getRootNode = () => canvas;
138
- root.current = createRoot(canvas);
139
- setCanvas(canvas);
140
- function handleTouch(gestureEvent, type) {
141
- gestureEvent.persist();
142
- canvas.dispatchEvent(Object.assign(gestureEvent.nativeEvent, {
143
- type,
144
- offsetX: gestureEvent.nativeEvent.locationX,
145
- offsetY: gestureEvent.nativeEvent.locationY,
146
- pointerType: 'touch',
147
- pointerId: gestureEvent.nativeEvent.identifier
148
- }));
149
- return true;
150
- }
151
- const responder = PanResponder.create({
152
- onStartShouldSetPanResponder: () => true,
153
- onMoveShouldSetPanResponder: () => true,
154
- onMoveShouldSetPanResponderCapture: () => true,
155
- onPanResponderTerminationRequest: () => true,
156
- onStartShouldSetPanResponderCapture: e => handleTouch(e, 'pointercapture'),
157
- onPanResponderStart: e => handleTouch(e, 'pointerdown'),
158
- onPanResponderMove: e => handleTouch(e, 'pointermove'),
159
- onPanResponderEnd: (e, state) => {
160
- handleTouch(e, 'pointerup');
161
- if (Math.hypot(state.dx, state.dy) < 20) handleTouch(e, 'click');
162
- },
163
- onPanResponderRelease: e => handleTouch(e, 'pointerleave'),
164
- onPanResponderTerminate: e => handleTouch(e, 'lostpointercapture'),
165
- onPanResponderReject: e => handleTouch(e, 'lostpointercapture')
166
- });
167
- setBind(responder.panHandlers);
168
- }, []);
169
- useIsomorphicLayoutEffect(() => {
170
- if (root.current && width > 0 && height > 0) {
171
- async function run() {
172
- await root.current.configure({
173
- gl,
174
- events,
175
- shadows,
176
- linear,
177
- flat,
178
- legacy,
179
- orthographic,
180
- frameloop,
181
- performance,
182
- raycaster,
183
- camera,
184
- scene,
185
- // expo-gl can only render at native dpr/resolution
186
- // https://github.com/expo/expo-three/issues/39
187
- dpr: PixelRatio.get(),
188
- size: {
189
- width,
190
- height,
191
- top,
192
- left
193
- },
194
- // Pass mutable reference to onPointerMissed so it's free to update
195
- onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
196
- // Overwrite onCreated to apply RN bindings
197
- onCreated: state => {
198
- // Bind render to RN bridge
199
- const context = state.gl.getContext();
200
- const renderFrame = state.gl.render.bind(state.gl);
201
- state.gl.render = (scene, camera) => {
202
- renderFrame(scene, camera);
203
- context.endFrameEXP();
204
- };
205
- return onCreated == null ? void 0 : onCreated(state);
206
- }
207
- });
208
- root.current.render( /*#__PURE__*/jsx(Bridge, {
209
- children: /*#__PURE__*/jsx(ErrorBoundary, {
210
- set: setError,
211
- children: /*#__PURE__*/jsx(React.Suspense, {
212
- fallback: /*#__PURE__*/jsx(Block, {
213
- set: setBlock
214
- }),
215
- children: children != null ? children : null
216
- })
217
- })
218
- }));
219
- }
220
- run();
221
- }
222
- });
223
- React.useEffect(() => {
224
- if (canvas) {
225
- return () => unmountComponentAtNode(canvas);
226
- }
227
- }, [canvas]);
228
- return /*#__PURE__*/jsxs(_View, {
229
- ...props,
230
- ref: viewRef,
231
- onLayout: onLayout,
232
- style: {
233
- flex: 1,
234
- ...style
235
- },
236
- children: [width > 0 && /*#__PURE__*/jsx(GLView, {
237
- msaaSamples: antialias ? 4 : 0,
238
- onContextCreate: onContextCreate,
239
- style: StyleSheet.absoluteFill
240
- }), /*#__PURE__*/jsx(_View, {
241
- style: StyleSheet.absoluteFill,
242
- pointerEvents: pointerEvents,
243
- ...bind
244
- })]
245
- });
246
- }
247
-
248
- /**
249
- * A native canvas which accepts threejs elements as children.
250
- * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
251
- */
252
- function Canvas(props) {
253
- return /*#__PURE__*/jsx(FiberProvider, {
254
- children: /*#__PURE__*/jsx(CanvasImpl, {
255
- ...props
256
- })
257
- });
258
- }
259
-
260
- /** Default R3F event manager for react-native */
261
- function createTouchEvents(store) {
262
- const {
263
- handlePointer
264
- } = createEvents(store);
265
- const handleTouch = (event, name) => {
266
- event.persist()
267
-
268
- // Apply offset
269
- ;
270
- event.nativeEvent.offsetX = event.nativeEvent.locationX;
271
- event.nativeEvent.offsetY = event.nativeEvent.locationY;
272
-
273
- // Emulate DOM event
274
- const callback = handlePointer(name);
275
- callback(event.nativeEvent);
276
- return true;
277
- };
278
- const responder = PanResponder.create({
279
- onStartShouldSetPanResponder: () => true,
280
- onMoveShouldSetPanResponder: () => true,
281
- onMoveShouldSetPanResponderCapture: () => true,
282
- onPanResponderTerminationRequest: () => true,
283
- onStartShouldSetPanResponderCapture: e => handleTouch(e, 'onPointerCapture'),
284
- onPanResponderStart: e => handleTouch(e, 'onPointerDown'),
285
- onPanResponderMove: e => handleTouch(e, 'onPointerMove'),
286
- onPanResponderEnd: (e, state) => {
287
- handleTouch(e, 'onPointerUp');
288
- if (Math.hypot(state.dx, state.dy) < 20) handleTouch(e, 'onClick');
289
- },
290
- onPanResponderRelease: e => handleTouch(e, 'onPointerLeave'),
291
- onPanResponderTerminate: e => handleTouch(e, 'onLostPointerCapture'),
292
- onPanResponderReject: e => handleTouch(e, 'onLostPointerCapture')
293
- });
294
- return {
295
- priority: 1,
296
- enabled: true,
297
- compute(event, state, previous) {
298
- // https://github.com/pmndrs/react-three-fiber/pull/782
299
- // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
300
- state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
301
- state.raycaster.setFromCamera(state.pointer, state.camera);
302
- },
303
- connected: undefined,
304
- handlers: responder.panHandlers,
305
- update: () => {
306
- var _internal$lastEvent;
307
- const {
308
- events,
309
- internal
310
- } = store.getState();
311
- if ((_internal$lastEvent = internal.lastEvent) != null && _internal$lastEvent.current && events.handlers) {
312
- handlePointer('onPointerMove')(internal.lastEvent.current);
313
- }
314
- },
315
- connect: () => {
316
- const {
317
- set,
318
- events
319
- } = store.getState();
320
- events.disconnect == null ? void 0 : events.disconnect();
321
- set(state => ({
322
- events: {
323
- ...state.events,
324
- connected: true
325
- }
326
- }));
327
- },
328
- disconnect: () => {
329
- const {
330
- set
331
- } = store.getState();
332
- set(state => ({
333
- events: {
334
- ...state.events,
335
- connected: false
336
- }
337
- }));
338
- }
339
- };
340
- }
341
-
342
- // Conditionally import expo-file-system/legacy to support Expo 54
343
- const getFileSystem = () => {
344
- try {
345
- return require('expo-file-system/legacy');
346
- } catch {
347
- return require('expo-file-system');
348
- }
349
- };
350
- const fs = getFileSystem();
351
-
352
- // http://stackoverflow.com/questions/105034
353
- function uuidv4() {
354
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
355
- const r = Math.random() * 16 | 0,
356
- v = c == 'x' ? r : r & 0x3 | 0x8;
357
- return v.toString(16);
358
- });
359
- }
360
- async function getAsset(input) {
361
- if (typeof input === 'string') {
362
- var _NativeModules$BlobMo;
363
- // Don't process storage
364
- if (input.startsWith('file:')) return input;
365
-
366
- // Unpack Blobs from react-native BlobManager
367
- // https://github.com/facebook/react-native/issues/22681#issuecomment-523258955
368
- if (input.startsWith('blob:') || input.startsWith((_NativeModules$BlobMo = NativeModules.BlobModule) == null ? void 0 : _NativeModules$BlobMo.BLOB_URI_SCHEME)) {
369
- const blob = await new Promise((res, rej) => {
370
- const xhr = new XMLHttpRequest();
371
- xhr.open('GET', input);
372
- xhr.responseType = 'blob';
373
- xhr.onload = () => res(xhr.response);
374
- xhr.onerror = rej;
375
- xhr.send();
376
- });
377
- const data = await new Promise((res, rej) => {
378
- const reader = new FileReader();
379
- reader.onload = () => res(reader.result);
380
- reader.onerror = rej;
381
- reader.readAsText(blob);
382
- });
383
- input = `data:${blob.type};base64,${data}`;
384
- }
385
-
386
- // Create safe URI for JSI serialization
387
- if (input.startsWith('data:')) {
388
- const [header, data] = input.split(';base64,');
389
- const [, type] = header.split('/');
390
- const uri = fs.cacheDirectory + uuidv4() + `.${type}`;
391
- await fs.writeAsStringAsync(uri, data, {
392
- encoding: fs.EncodingType.Base64
393
- });
394
- return uri;
395
- }
396
- }
397
-
398
- // Download bundler module or external URL
399
- const asset = await Asset.fromModule(input).downloadAsync();
400
- let uri = asset.localUri || asset.uri;
401
-
402
- // Unpack assets in Android Release Mode
403
- if (!uri.includes(':')) {
404
- const file = `${fs.cacheDirectory}ExponentAsset-${asset.hash}.${asset.type}`;
405
- await fs.copyAsync({
406
- from: uri,
407
- to: file
408
- });
409
- uri = file;
410
- }
411
- return uri;
412
- }
413
- function polyfills() {
414
- // Patch Blob for ArrayBuffer and URL if unsupported
415
- // https://github.com/facebook/react-native/pull/39276
416
- // https://github.com/pmndrs/react-three-fiber/issues/3058
417
- if (Platform.OS !== 'web') {
418
- try {
419
- const blob = new Blob([new ArrayBuffer(4)]);
420
- const url = URL.createObjectURL(blob);
421
- URL.revokeObjectURL(url);
422
- } catch (_) {
423
- var _BlobManagerModule$de;
424
- const BlobManagerModule = require('react-native/Libraries/Blob/BlobManager.js');
425
- const BlobManager = (_BlobManagerModule$de = BlobManagerModule.default) != null ? _BlobManagerModule$de : BlobManagerModule;
426
- const createObjectURL = URL.createObjectURL;
427
- URL.createObjectURL = function (blob) {
428
- if (blob.data._base64) {
429
- return `data:${blob.type};base64,${blob.data._base64}`;
430
- }
431
- return createObjectURL(blob);
432
- };
433
- const createFromParts = BlobManager.createFromParts;
434
- BlobManager.createFromParts = function (parts, options) {
435
- parts = parts.map(part => {
436
- if (part instanceof ArrayBuffer || ArrayBuffer.isView(part)) {
437
- part = fromByteArray(new Uint8Array(part));
438
- }
439
- return part;
440
- });
441
- const blob = createFromParts(parts, options);
442
-
443
- // Always enable slow but safe path for iOS (previously for Android unauth)
444
- // https://github.com/pmndrs/react-three-fiber/issues/3075
445
- // if (!NativeModules.BlobModule?.BLOB_URI_SCHEME) {
446
- blob.data._base64 = '';
447
- for (const part of parts) {
448
- var _data$_base, _data;
449
- blob.data._base64 += (_data$_base = (_data = part.data) == null ? void 0 : _data._base64) != null ? _data$_base : part;
450
- }
451
- // }
452
-
453
- return blob;
454
- };
455
- }
456
- }
457
-
458
- // Don't pre-process urls, let expo-asset generate an absolute URL
459
- const extractUrlBase = THREE.LoaderUtils.extractUrlBase.bind(THREE.LoaderUtils);
460
- THREE.LoaderUtils.extractUrlBase = url => typeof url === 'string' ? extractUrlBase(url) : './';
461
-
462
- // There's no Image in native, so create a data texture instead
463
- THREE.TextureLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
464
- if (this.path && typeof url === 'string') url = this.path + url;
465
- const texture = new THREE.Texture();
466
- getAsset(url).then(async uri => {
467
- // https://github.com/expo/expo-three/pull/266
468
- const {
469
- width,
470
- height
471
- } = await new Promise((res, rej) => Image.getSize(uri, (width, height) => res({
472
- width,
473
- height
474
- }), rej));
475
- texture.image = {
476
- // Special case for EXGLImageUtils::loadImage
477
- data: {
478
- localUri: uri
479
- },
480
- width,
481
- height
482
- };
483
- texture.flipY = true; // Since expo-gl@12.4.0
484
- texture.needsUpdate = true;
485
-
486
- // Force non-DOM upload for EXGL texImage2D
487
- // @ts-expect-error
488
- texture.isDataTexture = true;
489
- onLoad == null ? void 0 : onLoad(texture);
490
- }).catch(onError);
491
- return texture;
492
- };
493
-
494
- // Fetches assets via FS
495
- THREE.FileLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
496
- if (this.path && typeof url === 'string') url = this.path + url;
497
- this.manager.itemStart(url);
498
- getAsset(url).then(async uri => {
499
- const base64 = await fs.readAsStringAsync(uri, {
500
- encoding: fs.EncodingType.Base64
501
- });
502
- const data = Buffer.from(base64, 'base64');
503
- onLoad == null ? void 0 : onLoad(data.buffer);
504
- }).catch(error => {
505
- onError == null ? void 0 : onError(error);
506
- this.manager.itemError(url);
507
- }).finally(() => {
508
- this.manager.itemEnd(url);
509
- });
510
- };
511
- }
512
-
513
- if (Platform.OS !== 'web') polyfills();
514
-
515
- export { Canvas, createTouchEvents as events };
@@ -1,5 +0,0 @@
1
- {
2
- "main": "dist/react-three-fiber-native.cjs.js",
3
- "module": "dist/react-three-fiber-native.esm.js",
4
- "types": "dist/react-three-fiber-native.cjs.d.ts"
5
- }