@react-three/fiber 9.0.0-rc.4 → 9.0.0-rc.5

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