@react-three/fiber 7.0.25 → 7.0.26
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.
- package/CHANGELOG.md +6 -0
- package/dist/declarations/src/core/store.d.ts +2 -0
- package/dist/react-three-fiber.cjs.dev.js +6 -9
- package/dist/react-three-fiber.cjs.prod.js +6 -9
- package/dist/react-three-fiber.esm.js +6 -9
- package/native/dist/react-three-fiber-native.cjs.d.ts +1 -11
- package/native/dist/react-three-fiber-native.cjs.dev.js +358 -0
- package/native/dist/react-three-fiber-native.cjs.js +6 -15
- package/native/dist/react-three-fiber-native.cjs.prod.js +358 -0
- package/native/dist/react-three-fiber-native.esm.js +306 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -90,6 +90,8 @@ export declare type FilterFunction = (items: THREE.Intersection[], state: RootSt
|
|
|
90
90
|
export declare type ComputeOffsetsFunction = (event: any, state: RootState) => {
|
|
91
91
|
offsetX: number;
|
|
92
92
|
offsetY: number;
|
|
93
|
+
width?: number;
|
|
94
|
+
height?: number;
|
|
93
95
|
};
|
|
94
96
|
export declare type StoreProps = {
|
|
95
97
|
gl: THREE.WebGLRenderer;
|
|
@@ -114,7 +114,7 @@ function createEvents(store) {
|
|
|
114
114
|
/** Sets up defaultRaycaster */
|
|
115
115
|
|
|
116
116
|
function prepareRay(event) {
|
|
117
|
-
var
|
|
117
|
+
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
118
118
|
|
|
119
119
|
const state = store.getState();
|
|
120
120
|
const {
|
|
@@ -125,14 +125,11 @@ function createEvents(store) {
|
|
|
125
125
|
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
126
126
|
// Events trigger outside of canvas when moved
|
|
127
127
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
width,
|
|
134
|
-
height
|
|
135
|
-
} = size;
|
|
128
|
+
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
129
|
+
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
130
|
+
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
131
|
+
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
132
|
+
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
136
133
|
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
137
134
|
raycaster.setFromCamera(mouse, camera);
|
|
138
135
|
}
|
|
@@ -114,7 +114,7 @@ function createEvents(store) {
|
|
|
114
114
|
/** Sets up defaultRaycaster */
|
|
115
115
|
|
|
116
116
|
function prepareRay(event) {
|
|
117
|
-
var
|
|
117
|
+
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
118
118
|
|
|
119
119
|
const state = store.getState();
|
|
120
120
|
const {
|
|
@@ -125,14 +125,11 @@ function createEvents(store) {
|
|
|
125
125
|
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
126
126
|
// Events trigger outside of canvas when moved
|
|
127
127
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
width,
|
|
134
|
-
height
|
|
135
|
-
} = size;
|
|
128
|
+
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
129
|
+
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
130
|
+
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
131
|
+
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
132
|
+
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
136
133
|
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
137
134
|
raycaster.setFromCamera(mouse, camera);
|
|
138
135
|
}
|
|
@@ -81,7 +81,7 @@ function createEvents(store) {
|
|
|
81
81
|
/** Sets up defaultRaycaster */
|
|
82
82
|
|
|
83
83
|
function prepareRay(event) {
|
|
84
|
-
var
|
|
84
|
+
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
85
85
|
|
|
86
86
|
const state = store.getState();
|
|
87
87
|
const {
|
|
@@ -92,14 +92,11 @@ function createEvents(store) {
|
|
|
92
92
|
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
93
93
|
// Events trigger outside of canvas when moved
|
|
94
94
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
width,
|
|
101
|
-
height
|
|
102
|
-
} = size;
|
|
95
|
+
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
96
|
+
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
97
|
+
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
98
|
+
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
99
|
+
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
103
100
|
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
104
101
|
raycaster.setFromCamera(mouse, camera);
|
|
105
102
|
}
|
|
@@ -1,11 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// you should run `yarn` or `yarn preconstruct dev` if preconstruct dev isn't in your postinstall hook
|
|
3
|
-
|
|
4
|
-
// curious why you need to?
|
|
5
|
-
// this file exists so that you can import from the entrypoint normally
|
|
6
|
-
// except that it points to your source file and you don't need to run build constantly
|
|
7
|
-
// which means we need to re-export all of the modules from your source file
|
|
8
|
-
// and since export * doesn't include default exports, we need to read your source file
|
|
9
|
-
// to check for a default export and re-export it if it exists
|
|
10
|
-
// it's not ideal, but it works pretty well ¯\_(ツ)_/¯
|
|
11
|
-
export * from "../../src/native";
|
|
1
|
+
export * from "../../dist/declarations/src/native";
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var THREE = require('three');
|
|
6
|
+
var expoAsset = require('expo-asset');
|
|
7
|
+
var index = require('../../dist/index-95c17855.cjs.dev.js');
|
|
8
|
+
var _extends = require('@babel/runtime/helpers/extends');
|
|
9
|
+
var React = require('react');
|
|
10
|
+
var reactNative = require('react-native');
|
|
11
|
+
var expoGl = require('expo-gl');
|
|
12
|
+
var Pressability = require('react-native/Libraries/Pressability/Pressability');
|
|
13
|
+
require('suspend-react');
|
|
14
|
+
require('react-reconciler/constants');
|
|
15
|
+
require('zustand');
|
|
16
|
+
require('react-reconciler');
|
|
17
|
+
require('scheduler');
|
|
18
|
+
|
|
19
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
20
|
+
|
|
21
|
+
function _interopNamespace(e) {
|
|
22
|
+
if (e && e.__esModule) return e;
|
|
23
|
+
var n = Object.create(null);
|
|
24
|
+
if (e) {
|
|
25
|
+
Object.keys(e).forEach(function (k) {
|
|
26
|
+
if (k !== 'default') {
|
|
27
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
28
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () {
|
|
31
|
+
return e[k];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
n['default'] = e;
|
|
38
|
+
return Object.freeze(n);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
42
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
43
|
+
var Pressability__default = /*#__PURE__*/_interopDefault(Pressability);
|
|
44
|
+
|
|
45
|
+
const EVENTS = {
|
|
46
|
+
PRESS: 'onPress',
|
|
47
|
+
PRESSIN: 'onPressIn',
|
|
48
|
+
PRESSOUT: 'onPressOut',
|
|
49
|
+
LONGPRESS: 'onLongPress',
|
|
50
|
+
HOVERIN: 'onHoverIn',
|
|
51
|
+
HOVEROUT: 'onHoverOut',
|
|
52
|
+
PRESSMOVE: 'onPressMove'
|
|
53
|
+
};
|
|
54
|
+
const DOM_EVENTS = {
|
|
55
|
+
[EVENTS.PRESS]: 'onClick',
|
|
56
|
+
[EVENTS.PRESSIN]: 'onPointerDown',
|
|
57
|
+
[EVENTS.PRESSOUT]: 'onPointerUp',
|
|
58
|
+
[EVENTS.LONGPRESS]: 'onDoubleClick',
|
|
59
|
+
[EVENTS.HOVERIN]: 'onPointerOver',
|
|
60
|
+
[EVENTS.HOVEROUT]: 'onPointerOut',
|
|
61
|
+
[EVENTS.PRESSMOVE]: 'onPointerMove'
|
|
62
|
+
};
|
|
63
|
+
function createTouchEvents(store) {
|
|
64
|
+
const {
|
|
65
|
+
handlePointer
|
|
66
|
+
} = index.createEvents(store);
|
|
67
|
+
|
|
68
|
+
const handleTouch = (event, name) => {
|
|
69
|
+
event.persist() // Apply offset
|
|
70
|
+
;
|
|
71
|
+
event.nativeEvent.offsetX = event.nativeEvent.locationX;
|
|
72
|
+
event.nativeEvent.offsetY = event.nativeEvent.locationY; // Emulate DOM event
|
|
73
|
+
|
|
74
|
+
const callback = handlePointer(DOM_EVENTS[name]);
|
|
75
|
+
return callback(event.nativeEvent);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
connected: false,
|
|
80
|
+
handlers: Object.values(EVENTS).reduce((acc, name) => ({ ...acc,
|
|
81
|
+
[name]: event => handleTouch(event, name)
|
|
82
|
+
}), {}),
|
|
83
|
+
connect: () => {
|
|
84
|
+
const {
|
|
85
|
+
set,
|
|
86
|
+
events
|
|
87
|
+
} = store.getState();
|
|
88
|
+
events.disconnect == null ? void 0 : events.disconnect();
|
|
89
|
+
const connected = new Pressability__default['default'](events == null ? void 0 : events.handlers);
|
|
90
|
+
set(state => ({
|
|
91
|
+
events: { ...state.events,
|
|
92
|
+
connected
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
const handlers = connected.getEventHandlers();
|
|
96
|
+
return handlers;
|
|
97
|
+
},
|
|
98
|
+
disconnect: () => {
|
|
99
|
+
const {
|
|
100
|
+
set,
|
|
101
|
+
events
|
|
102
|
+
} = store.getState();
|
|
103
|
+
|
|
104
|
+
if (events.connected) {
|
|
105
|
+
events.connected.reset();
|
|
106
|
+
set(state => ({
|
|
107
|
+
events: { ...state.events,
|
|
108
|
+
connected: false
|
|
109
|
+
}
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
|
|
117
|
+
|
|
118
|
+
function Block({
|
|
119
|
+
set
|
|
120
|
+
}) {
|
|
121
|
+
React__namespace.useLayoutEffect(() => {
|
|
122
|
+
set(new Promise(() => null));
|
|
123
|
+
return () => set(false);
|
|
124
|
+
}, [set]);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class ErrorBoundary extends React__namespace.Component {
|
|
129
|
+
constructor(...args) {
|
|
130
|
+
super(...args);
|
|
131
|
+
this.state = {
|
|
132
|
+
error: false
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
componentDidCatch(error) {
|
|
137
|
+
this.props.set(error);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
render() {
|
|
141
|
+
return this.state.error ? null : this.props.children;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
ErrorBoundary.getDerivedStateFromError = () => ({
|
|
147
|
+
error: true
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const Canvas = /*#__PURE__*/React__namespace.forwardRef(({
|
|
151
|
+
children,
|
|
152
|
+
fallback,
|
|
153
|
+
style,
|
|
154
|
+
events,
|
|
155
|
+
...props
|
|
156
|
+
}, forwardedRef) => {
|
|
157
|
+
// Create a known catalogue of Threejs-native elements
|
|
158
|
+
// This will include the entire THREE namespace by default, users can extend
|
|
159
|
+
// their own elements by using the createRoot API instead
|
|
160
|
+
React__namespace.useMemo(() => index.extend(THREE__namespace), []);
|
|
161
|
+
const [{
|
|
162
|
+
width,
|
|
163
|
+
height
|
|
164
|
+
}, setSize] = React__namespace.useState({
|
|
165
|
+
width: 0,
|
|
166
|
+
height: 0
|
|
167
|
+
});
|
|
168
|
+
const [canvas, setCanvas] = React__namespace.useState(null);
|
|
169
|
+
const [bind, setBind] = React__namespace.useState();
|
|
170
|
+
const canvasProps = index.pick(props, CANVAS_PROPS);
|
|
171
|
+
const viewProps = index.omit(props, CANVAS_PROPS);
|
|
172
|
+
const [block, setBlock] = React__namespace.useState(false);
|
|
173
|
+
const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
|
|
174
|
+
|
|
175
|
+
if (block) throw block; // Throw exception outwards if anything within canvas throws
|
|
176
|
+
|
|
177
|
+
if (error) throw error;
|
|
178
|
+
const onLayout = React__namespace.useCallback(e => {
|
|
179
|
+
const {
|
|
180
|
+
width,
|
|
181
|
+
height
|
|
182
|
+
} = e.nativeEvent.layout;
|
|
183
|
+
setSize({
|
|
184
|
+
width,
|
|
185
|
+
height
|
|
186
|
+
});
|
|
187
|
+
}, []);
|
|
188
|
+
const onContextCreate = React__namespace.useCallback(context => {
|
|
189
|
+
const canvasShim = {
|
|
190
|
+
width: context.drawingBufferWidth,
|
|
191
|
+
height: context.drawingBufferHeight,
|
|
192
|
+
style: {},
|
|
193
|
+
addEventListener: () => {},
|
|
194
|
+
removeEventListener: () => {},
|
|
195
|
+
clientHeight: context.drawingBufferHeight,
|
|
196
|
+
getContext: () => context
|
|
197
|
+
};
|
|
198
|
+
setCanvas(canvasShim);
|
|
199
|
+
}, []);
|
|
200
|
+
|
|
201
|
+
if (width > 0 && height > 0 && canvas) {
|
|
202
|
+
// Overwrite onCreated to apply RN bindings
|
|
203
|
+
const onCreated = state => {
|
|
204
|
+
// Bind events after creation
|
|
205
|
+
const handlers = state.events.connect == null ? void 0 : state.events.connect(canvas);
|
|
206
|
+
setBind(handlers); // Bind render to RN bridge
|
|
207
|
+
|
|
208
|
+
const context = state.gl.getContext();
|
|
209
|
+
const renderFrame = state.gl.render.bind(state.gl);
|
|
210
|
+
|
|
211
|
+
state.gl.render = (scene, camera) => {
|
|
212
|
+
renderFrame(scene, camera);
|
|
213
|
+
context.endFrameEXP();
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
return canvasProps == null ? void 0 : canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
index.createRoot(canvas, { ...canvasProps,
|
|
220
|
+
// expo-gl can only render at native dpr/resolution
|
|
221
|
+
// https://github.com/expo/expo-three/issues/39
|
|
222
|
+
dpr: reactNative.PixelRatio.get(),
|
|
223
|
+
size: {
|
|
224
|
+
width,
|
|
225
|
+
height
|
|
226
|
+
},
|
|
227
|
+
events: events || createTouchEvents,
|
|
228
|
+
onCreated
|
|
229
|
+
}).render( /*#__PURE__*/React__namespace.createElement(ErrorBoundary, {
|
|
230
|
+
set: setError
|
|
231
|
+
}, /*#__PURE__*/React__namespace.createElement(React__namespace.Suspense, {
|
|
232
|
+
fallback: /*#__PURE__*/React__namespace.createElement(Block, {
|
|
233
|
+
set: setBlock
|
|
234
|
+
})
|
|
235
|
+
}, children)));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
React__namespace.useEffect(() => {
|
|
239
|
+
return () => index.unmountComponentAtNode(canvas);
|
|
240
|
+
}, [canvas]);
|
|
241
|
+
return /*#__PURE__*/React__namespace.createElement(reactNative.View, _extends({}, viewProps, {
|
|
242
|
+
ref: forwardedRef,
|
|
243
|
+
onLayout: onLayout,
|
|
244
|
+
style: {
|
|
245
|
+
flex: 1,
|
|
246
|
+
...style
|
|
247
|
+
}
|
|
248
|
+
}, bind), width > 0 && /*#__PURE__*/React__namespace.createElement(expoGl.GLView, {
|
|
249
|
+
onContextCreate: onContextCreate,
|
|
250
|
+
style: reactNative.StyleSheet.absoluteFill
|
|
251
|
+
}));
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Generates an asset based on input type.
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
const getAsset = input => {
|
|
259
|
+
if (input instanceof expoAsset.Asset) return input;
|
|
260
|
+
|
|
261
|
+
switch (typeof input) {
|
|
262
|
+
case 'string':
|
|
263
|
+
return expoAsset.Asset.fromURI(input);
|
|
264
|
+
|
|
265
|
+
case 'number':
|
|
266
|
+
return expoAsset.Asset.fromModule(input);
|
|
267
|
+
|
|
268
|
+
default:
|
|
269
|
+
throw 'Invalid asset! Must be a URI or module.';
|
|
270
|
+
}
|
|
271
|
+
}; // Don't pre-process urls, let expo-asset generate an absolute URL
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
THREE__namespace.LoaderUtils.extractUrlBase = () => './'; // There's no Image in native, so create a data texture instead
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
THREE__namespace.TextureLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
|
|
278
|
+
const texture = new THREE__namespace.Texture(); // @ts-expect-error
|
|
279
|
+
|
|
280
|
+
texture.isDataTexture = true;
|
|
281
|
+
getAsset(url).downloadAsync().then(asset => {
|
|
282
|
+
texture.image = {
|
|
283
|
+
data: asset,
|
|
284
|
+
width: asset.width,
|
|
285
|
+
height: asset.height
|
|
286
|
+
};
|
|
287
|
+
texture.needsUpdate = true;
|
|
288
|
+
onLoad == null ? void 0 : onLoad(texture);
|
|
289
|
+
}).catch(onError);
|
|
290
|
+
return texture;
|
|
291
|
+
}; // Fetches assets via XMLHttpRequest
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
THREE__namespace.FileLoader.prototype.load = function (url, onLoad, onProgress, onError) {
|
|
295
|
+
if (this.path) url = this.path + url;
|
|
296
|
+
const request = new XMLHttpRequest();
|
|
297
|
+
getAsset(url).downloadAsync().then(asset => {
|
|
298
|
+
request.open('GET', asset.uri, true);
|
|
299
|
+
request.addEventListener('load', event => {
|
|
300
|
+
if (request.status === 200) {
|
|
301
|
+
onLoad == null ? void 0 : onLoad(request.response);
|
|
302
|
+
this.manager.itemEnd(url);
|
|
303
|
+
} else {
|
|
304
|
+
onError == null ? void 0 : onError(event);
|
|
305
|
+
this.manager.itemError(url);
|
|
306
|
+
this.manager.itemEnd(url);
|
|
307
|
+
}
|
|
308
|
+
}, false);
|
|
309
|
+
request.addEventListener('progress', event => {
|
|
310
|
+
onProgress == null ? void 0 : onProgress(event);
|
|
311
|
+
}, false);
|
|
312
|
+
request.addEventListener('error', event => {
|
|
313
|
+
onError == null ? void 0 : onError(event);
|
|
314
|
+
this.manager.itemError(url);
|
|
315
|
+
this.manager.itemEnd(url);
|
|
316
|
+
}, false);
|
|
317
|
+
request.addEventListener('abort', event => {
|
|
318
|
+
onError == null ? void 0 : onError(event);
|
|
319
|
+
this.manager.itemError(url);
|
|
320
|
+
this.manager.itemEnd(url);
|
|
321
|
+
}, false);
|
|
322
|
+
if (this.responseType) request.responseType = this.responseType;
|
|
323
|
+
if (this.withCredentials) request.withCredentials = this.withCredentials;
|
|
324
|
+
|
|
325
|
+
for (const header in this.requestHeader) {
|
|
326
|
+
request.setRequestHeader(header, this.requestHeader[header]);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
request.send(null);
|
|
330
|
+
this.manager.itemStart(url);
|
|
331
|
+
});
|
|
332
|
+
return request;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
exports.ReactThreeFiber = index.threeTypes;
|
|
336
|
+
exports._roots = index.roots;
|
|
337
|
+
exports.act = index.act;
|
|
338
|
+
exports.addAfterEffect = index.addAfterEffect;
|
|
339
|
+
exports.addEffect = index.addEffect;
|
|
340
|
+
exports.addTail = index.addTail;
|
|
341
|
+
exports.advance = index.advance;
|
|
342
|
+
exports.applyProps = index.applyProps;
|
|
343
|
+
exports.context = index.context;
|
|
344
|
+
exports.createPortal = index.createPortal;
|
|
345
|
+
exports.createRoot = index.createRoot;
|
|
346
|
+
exports.dispose = index.dispose;
|
|
347
|
+
exports.extend = index.extend;
|
|
348
|
+
exports.invalidate = index.invalidate;
|
|
349
|
+
exports.reconciler = index.reconciler;
|
|
350
|
+
exports.render = index.render;
|
|
351
|
+
exports.unmountComponentAtNode = index.unmountComponentAtNode;
|
|
352
|
+
exports.useFrame = index.useFrame;
|
|
353
|
+
exports.useGraph = index.useGraph;
|
|
354
|
+
exports.useLoader = index.useLoader;
|
|
355
|
+
exports.useStore = index.useStore;
|
|
356
|
+
exports.useThree = index.useThree;
|
|
357
|
+
exports.Canvas = Canvas;
|
|
358
|
+
exports.events = createTouchEvents;
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
// this file might look strange and you might be wondering what it's for
|
|
3
|
-
// it's lets you import your source files by importing this entrypoint
|
|
4
|
-
// as you would import it if it was built with preconstruct build
|
|
5
|
-
// this file is slightly different to some others though
|
|
6
|
-
// it has a require hook which compiles your code with Babel
|
|
7
|
-
// this means that you don't have to set up @babel/register or anything like that
|
|
8
|
-
// but you can still require this module and it'll be compiled
|
|
1
|
+
'use strict';
|
|
9
2
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
unregister();
|
|
3
|
+
if (process.env.NODE_ENV === "production") {
|
|
4
|
+
module.exports = require("./react-three-fiber-native.cjs.prod.js");
|
|
5
|
+
} else {
|
|
6
|
+
module.exports = require("./react-three-fiber-native.cjs.dev.js");
|
|
7
|
+
}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var THREE = require('three');
|
|
6
|
+
var expoAsset = require('expo-asset');
|
|
7
|
+
var index = require('../../dist/index-ff8b5912.cjs.prod.js');
|
|
8
|
+
var _extends = require('@babel/runtime/helpers/extends');
|
|
9
|
+
var React = require('react');
|
|
10
|
+
var reactNative = require('react-native');
|
|
11
|
+
var expoGl = require('expo-gl');
|
|
12
|
+
var Pressability = require('react-native/Libraries/Pressability/Pressability');
|
|
13
|
+
require('suspend-react');
|
|
14
|
+
require('react-reconciler/constants');
|
|
15
|
+
require('zustand');
|
|
16
|
+
require('react-reconciler');
|
|
17
|
+
require('scheduler');
|
|
18
|
+
|
|
19
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
20
|
+
|
|
21
|
+
function _interopNamespace(e) {
|
|
22
|
+
if (e && e.__esModule) return e;
|
|
23
|
+
var n = Object.create(null);
|
|
24
|
+
if (e) {
|
|
25
|
+
Object.keys(e).forEach(function (k) {
|
|
26
|
+
if (k !== 'default') {
|
|
27
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
28
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () {
|
|
31
|
+
return e[k];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
n['default'] = e;
|
|
38
|
+
return Object.freeze(n);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
42
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
43
|
+
var Pressability__default = /*#__PURE__*/_interopDefault(Pressability);
|
|
44
|
+
|
|
45
|
+
const EVENTS = {
|
|
46
|
+
PRESS: 'onPress',
|
|
47
|
+
PRESSIN: 'onPressIn',
|
|
48
|
+
PRESSOUT: 'onPressOut',
|
|
49
|
+
LONGPRESS: 'onLongPress',
|
|
50
|
+
HOVERIN: 'onHoverIn',
|
|
51
|
+
HOVEROUT: 'onHoverOut',
|
|
52
|
+
PRESSMOVE: 'onPressMove'
|
|
53
|
+
};
|
|
54
|
+
const DOM_EVENTS = {
|
|
55
|
+
[EVENTS.PRESS]: 'onClick',
|
|
56
|
+
[EVENTS.PRESSIN]: 'onPointerDown',
|
|
57
|
+
[EVENTS.PRESSOUT]: 'onPointerUp',
|
|
58
|
+
[EVENTS.LONGPRESS]: 'onDoubleClick',
|
|
59
|
+
[EVENTS.HOVERIN]: 'onPointerOver',
|
|
60
|
+
[EVENTS.HOVEROUT]: 'onPointerOut',
|
|
61
|
+
[EVENTS.PRESSMOVE]: 'onPointerMove'
|
|
62
|
+
};
|
|
63
|
+
function createTouchEvents(store) {
|
|
64
|
+
const {
|
|
65
|
+
handlePointer
|
|
66
|
+
} = index.createEvents(store);
|
|
67
|
+
|
|
68
|
+
const handleTouch = (event, name) => {
|
|
69
|
+
event.persist() // Apply offset
|
|
70
|
+
;
|
|
71
|
+
event.nativeEvent.offsetX = event.nativeEvent.locationX;
|
|
72
|
+
event.nativeEvent.offsetY = event.nativeEvent.locationY; // Emulate DOM event
|
|
73
|
+
|
|
74
|
+
const callback = handlePointer(DOM_EVENTS[name]);
|
|
75
|
+
return callback(event.nativeEvent);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
connected: false,
|
|
80
|
+
handlers: Object.values(EVENTS).reduce((acc, name) => ({ ...acc,
|
|
81
|
+
[name]: event => handleTouch(event, name)
|
|
82
|
+
}), {}),
|
|
83
|
+
connect: () => {
|
|
84
|
+
const {
|
|
85
|
+
set,
|
|
86
|
+
events
|
|
87
|
+
} = store.getState();
|
|
88
|
+
events.disconnect == null ? void 0 : events.disconnect();
|
|
89
|
+
const connected = new Pressability__default['default'](events == null ? void 0 : events.handlers);
|
|
90
|
+
set(state => ({
|
|
91
|
+
events: { ...state.events,
|
|
92
|
+
connected
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
const handlers = connected.getEventHandlers();
|
|
96
|
+
return handlers;
|
|
97
|
+
},
|
|
98
|
+
disconnect: () => {
|
|
99
|
+
const {
|
|
100
|
+
set,
|
|
101
|
+
events
|
|
102
|
+
} = store.getState();
|
|
103
|
+
|
|
104
|
+
if (events.connected) {
|
|
105
|
+
events.connected.reset();
|
|
106
|
+
set(state => ({
|
|
107
|
+
events: { ...state.events,
|
|
108
|
+
connected: false
|
|
109
|
+
}
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
|
|
117
|
+
|
|
118
|
+
function Block({
|
|
119
|
+
set
|
|
120
|
+
}) {
|
|
121
|
+
React__namespace.useLayoutEffect(() => {
|
|
122
|
+
set(new Promise(() => null));
|
|
123
|
+
return () => set(false);
|
|
124
|
+
}, [set]);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
class ErrorBoundary extends React__namespace.Component {
|
|
129
|
+
constructor(...args) {
|
|
130
|
+
super(...args);
|
|
131
|
+
this.state = {
|
|
132
|
+
error: false
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
componentDidCatch(error) {
|
|
137
|
+
this.props.set(error);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
render() {
|
|
141
|
+
return this.state.error ? null : this.props.children;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
ErrorBoundary.getDerivedStateFromError = () => ({
|
|
147
|
+
error: true
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const Canvas = /*#__PURE__*/React__namespace.forwardRef(({
|
|
151
|
+
children,
|
|
152
|
+
fallback,
|
|
153
|
+
style,
|
|
154
|
+
events,
|
|
155
|
+
...props
|
|
156
|
+
}, forwardedRef) => {
|
|
157
|
+
// Create a known catalogue of Threejs-native elements
|
|
158
|
+
// This will include the entire THREE namespace by default, users can extend
|
|
159
|
+
// their own elements by using the createRoot API instead
|
|
160
|
+
React__namespace.useMemo(() => index.extend(THREE__namespace), []);
|
|
161
|
+
const [{
|
|
162
|
+
width,
|
|
163
|
+
height
|
|
164
|
+
}, setSize] = React__namespace.useState({
|
|
165
|
+
width: 0,
|
|
166
|
+
height: 0
|
|
167
|
+
});
|
|
168
|
+
const [canvas, setCanvas] = React__namespace.useState(null);
|
|
169
|
+
const [bind, setBind] = React__namespace.useState();
|
|
170
|
+
const canvasProps = index.pick(props, CANVAS_PROPS);
|
|
171
|
+
const viewProps = index.omit(props, CANVAS_PROPS);
|
|
172
|
+
const [block, setBlock] = React__namespace.useState(false);
|
|
173
|
+
const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
|
|
174
|
+
|
|
175
|
+
if (block) throw block; // Throw exception outwards if anything within canvas throws
|
|
176
|
+
|
|
177
|
+
if (error) throw error;
|
|
178
|
+
const onLayout = React__namespace.useCallback(e => {
|
|
179
|
+
const {
|
|
180
|
+
width,
|
|
181
|
+
height
|
|
182
|
+
} = e.nativeEvent.layout;
|
|
183
|
+
setSize({
|
|
184
|
+
width,
|
|
185
|
+
height
|
|
186
|
+
});
|
|
187
|
+
}, []);
|
|
188
|
+
const onContextCreate = React__namespace.useCallback(context => {
|
|
189
|
+
const canvasShim = {
|
|
190
|
+
width: context.drawingBufferWidth,
|
|
191
|
+
height: context.drawingBufferHeight,
|
|
192
|
+
style: {},
|
|
193
|
+
addEventListener: () => {},
|
|
194
|
+
removeEventListener: () => {},
|
|
195
|
+
clientHeight: context.drawingBufferHeight,
|
|
196
|
+
getContext: () => context
|
|
197
|
+
};
|
|
198
|
+
setCanvas(canvasShim);
|
|
199
|
+
}, []);
|
|
200
|
+
|
|
201
|
+
if (width > 0 && height > 0 && canvas) {
|
|
202
|
+
// Overwrite onCreated to apply RN bindings
|
|
203
|
+
const onCreated = state => {
|
|
204
|
+
// Bind events after creation
|
|
205
|
+
const handlers = state.events.connect == null ? void 0 : state.events.connect(canvas);
|
|
206
|
+
setBind(handlers); // Bind render to RN bridge
|
|
207
|
+
|
|
208
|
+
const context = state.gl.getContext();
|
|
209
|
+
const renderFrame = state.gl.render.bind(state.gl);
|
|
210
|
+
|
|
211
|
+
state.gl.render = (scene, camera) => {
|
|
212
|
+
renderFrame(scene, camera);
|
|
213
|
+
context.endFrameEXP();
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
return canvasProps == null ? void 0 : canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
index.createRoot(canvas, { ...canvasProps,
|
|
220
|
+
// expo-gl can only render at native dpr/resolution
|
|
221
|
+
// https://github.com/expo/expo-three/issues/39
|
|
222
|
+
dpr: reactNative.PixelRatio.get(),
|
|
223
|
+
size: {
|
|
224
|
+
width,
|
|
225
|
+
height
|
|
226
|
+
},
|
|
227
|
+
events: events || createTouchEvents,
|
|
228
|
+
onCreated
|
|
229
|
+
}).render( /*#__PURE__*/React__namespace.createElement(ErrorBoundary, {
|
|
230
|
+
set: setError
|
|
231
|
+
}, /*#__PURE__*/React__namespace.createElement(React__namespace.Suspense, {
|
|
232
|
+
fallback: /*#__PURE__*/React__namespace.createElement(Block, {
|
|
233
|
+
set: setBlock
|
|
234
|
+
})
|
|
235
|
+
}, children)));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
React__namespace.useEffect(() => {
|
|
239
|
+
return () => index.unmountComponentAtNode(canvas);
|
|
240
|
+
}, [canvas]);
|
|
241
|
+
return /*#__PURE__*/React__namespace.createElement(reactNative.View, _extends({}, viewProps, {
|
|
242
|
+
ref: forwardedRef,
|
|
243
|
+
onLayout: onLayout,
|
|
244
|
+
style: {
|
|
245
|
+
flex: 1,
|
|
246
|
+
...style
|
|
247
|
+
}
|
|
248
|
+
}, bind), width > 0 && /*#__PURE__*/React__namespace.createElement(expoGl.GLView, {
|
|
249
|
+
onContextCreate: onContextCreate,
|
|
250
|
+
style: reactNative.StyleSheet.absoluteFill
|
|
251
|
+
}));
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Generates an asset based on input type.
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
const getAsset = input => {
|
|
259
|
+
if (input instanceof expoAsset.Asset) return input;
|
|
260
|
+
|
|
261
|
+
switch (typeof input) {
|
|
262
|
+
case 'string':
|
|
263
|
+
return expoAsset.Asset.fromURI(input);
|
|
264
|
+
|
|
265
|
+
case 'number':
|
|
266
|
+
return expoAsset.Asset.fromModule(input);
|
|
267
|
+
|
|
268
|
+
default:
|
|
269
|
+
throw 'Invalid asset! Must be a URI or module.';
|
|
270
|
+
}
|
|
271
|
+
}; // Don't pre-process urls, let expo-asset generate an absolute URL
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
THREE__namespace.LoaderUtils.extractUrlBase = () => './'; // There's no Image in native, so create a data texture instead
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
THREE__namespace.TextureLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
|
|
278
|
+
const texture = new THREE__namespace.Texture(); // @ts-expect-error
|
|
279
|
+
|
|
280
|
+
texture.isDataTexture = true;
|
|
281
|
+
getAsset(url).downloadAsync().then(asset => {
|
|
282
|
+
texture.image = {
|
|
283
|
+
data: asset,
|
|
284
|
+
width: asset.width,
|
|
285
|
+
height: asset.height
|
|
286
|
+
};
|
|
287
|
+
texture.needsUpdate = true;
|
|
288
|
+
onLoad == null ? void 0 : onLoad(texture);
|
|
289
|
+
}).catch(onError);
|
|
290
|
+
return texture;
|
|
291
|
+
}; // Fetches assets via XMLHttpRequest
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
THREE__namespace.FileLoader.prototype.load = function (url, onLoad, onProgress, onError) {
|
|
295
|
+
if (this.path) url = this.path + url;
|
|
296
|
+
const request = new XMLHttpRequest();
|
|
297
|
+
getAsset(url).downloadAsync().then(asset => {
|
|
298
|
+
request.open('GET', asset.uri, true);
|
|
299
|
+
request.addEventListener('load', event => {
|
|
300
|
+
if (request.status === 200) {
|
|
301
|
+
onLoad == null ? void 0 : onLoad(request.response);
|
|
302
|
+
this.manager.itemEnd(url);
|
|
303
|
+
} else {
|
|
304
|
+
onError == null ? void 0 : onError(event);
|
|
305
|
+
this.manager.itemError(url);
|
|
306
|
+
this.manager.itemEnd(url);
|
|
307
|
+
}
|
|
308
|
+
}, false);
|
|
309
|
+
request.addEventListener('progress', event => {
|
|
310
|
+
onProgress == null ? void 0 : onProgress(event);
|
|
311
|
+
}, false);
|
|
312
|
+
request.addEventListener('error', event => {
|
|
313
|
+
onError == null ? void 0 : onError(event);
|
|
314
|
+
this.manager.itemError(url);
|
|
315
|
+
this.manager.itemEnd(url);
|
|
316
|
+
}, false);
|
|
317
|
+
request.addEventListener('abort', event => {
|
|
318
|
+
onError == null ? void 0 : onError(event);
|
|
319
|
+
this.manager.itemError(url);
|
|
320
|
+
this.manager.itemEnd(url);
|
|
321
|
+
}, false);
|
|
322
|
+
if (this.responseType) request.responseType = this.responseType;
|
|
323
|
+
if (this.withCredentials) request.withCredentials = this.withCredentials;
|
|
324
|
+
|
|
325
|
+
for (const header in this.requestHeader) {
|
|
326
|
+
request.setRequestHeader(header, this.requestHeader[header]);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
request.send(null);
|
|
330
|
+
this.manager.itemStart(url);
|
|
331
|
+
});
|
|
332
|
+
return request;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
exports.ReactThreeFiber = index.threeTypes;
|
|
336
|
+
exports._roots = index.roots;
|
|
337
|
+
exports.act = index.act;
|
|
338
|
+
exports.addAfterEffect = index.addAfterEffect;
|
|
339
|
+
exports.addEffect = index.addEffect;
|
|
340
|
+
exports.addTail = index.addTail;
|
|
341
|
+
exports.advance = index.advance;
|
|
342
|
+
exports.applyProps = index.applyProps;
|
|
343
|
+
exports.context = index.context;
|
|
344
|
+
exports.createPortal = index.createPortal;
|
|
345
|
+
exports.createRoot = index.createRoot;
|
|
346
|
+
exports.dispose = index.dispose;
|
|
347
|
+
exports.extend = index.extend;
|
|
348
|
+
exports.invalidate = index.invalidate;
|
|
349
|
+
exports.reconciler = index.reconciler;
|
|
350
|
+
exports.render = index.render;
|
|
351
|
+
exports.unmountComponentAtNode = index.unmountComponentAtNode;
|
|
352
|
+
exports.useFrame = index.useFrame;
|
|
353
|
+
exports.useGraph = index.useGraph;
|
|
354
|
+
exports.useLoader = index.useLoader;
|
|
355
|
+
exports.useStore = index.useStore;
|
|
356
|
+
exports.useThree = index.useThree;
|
|
357
|
+
exports.Canvas = Canvas;
|
|
358
|
+
exports.events = createTouchEvents;
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { Asset } from 'expo-asset';
|
|
3
|
+
import { c as createEvents, e as extend, p as pick, o as omit, a as createRoot, u as unmountComponentAtNode } from '../../dist/index-3f4e5f46.esm.js';
|
|
4
|
+
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 '../../dist/index-3f4e5f46.esm.js';
|
|
5
|
+
import _extends from '@babel/runtime/helpers/esm/extends';
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import { PixelRatio, View, StyleSheet } from 'react-native';
|
|
8
|
+
import { GLView } from 'expo-gl';
|
|
9
|
+
import Pressability from 'react-native/Libraries/Pressability/Pressability';
|
|
10
|
+
import 'suspend-react';
|
|
11
|
+
import 'react-reconciler/constants';
|
|
12
|
+
import 'zustand';
|
|
13
|
+
import 'react-reconciler';
|
|
14
|
+
import 'scheduler';
|
|
15
|
+
|
|
16
|
+
const EVENTS = {
|
|
17
|
+
PRESS: 'onPress',
|
|
18
|
+
PRESSIN: 'onPressIn',
|
|
19
|
+
PRESSOUT: 'onPressOut',
|
|
20
|
+
LONGPRESS: 'onLongPress',
|
|
21
|
+
HOVERIN: 'onHoverIn',
|
|
22
|
+
HOVEROUT: 'onHoverOut',
|
|
23
|
+
PRESSMOVE: 'onPressMove'
|
|
24
|
+
};
|
|
25
|
+
const DOM_EVENTS = {
|
|
26
|
+
[EVENTS.PRESS]: 'onClick',
|
|
27
|
+
[EVENTS.PRESSIN]: 'onPointerDown',
|
|
28
|
+
[EVENTS.PRESSOUT]: 'onPointerUp',
|
|
29
|
+
[EVENTS.LONGPRESS]: 'onDoubleClick',
|
|
30
|
+
[EVENTS.HOVERIN]: 'onPointerOver',
|
|
31
|
+
[EVENTS.HOVEROUT]: 'onPointerOut',
|
|
32
|
+
[EVENTS.PRESSMOVE]: 'onPointerMove'
|
|
33
|
+
};
|
|
34
|
+
function createTouchEvents(store) {
|
|
35
|
+
const {
|
|
36
|
+
handlePointer
|
|
37
|
+
} = createEvents(store);
|
|
38
|
+
|
|
39
|
+
const handleTouch = (event, name) => {
|
|
40
|
+
event.persist() // Apply offset
|
|
41
|
+
;
|
|
42
|
+
event.nativeEvent.offsetX = event.nativeEvent.locationX;
|
|
43
|
+
event.nativeEvent.offsetY = event.nativeEvent.locationY; // Emulate DOM event
|
|
44
|
+
|
|
45
|
+
const callback = handlePointer(DOM_EVENTS[name]);
|
|
46
|
+
return callback(event.nativeEvent);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
connected: false,
|
|
51
|
+
handlers: Object.values(EVENTS).reduce((acc, name) => ({ ...acc,
|
|
52
|
+
[name]: event => handleTouch(event, name)
|
|
53
|
+
}), {}),
|
|
54
|
+
connect: () => {
|
|
55
|
+
const {
|
|
56
|
+
set,
|
|
57
|
+
events
|
|
58
|
+
} = store.getState();
|
|
59
|
+
events.disconnect == null ? void 0 : events.disconnect();
|
|
60
|
+
const connected = new Pressability(events == null ? void 0 : events.handlers);
|
|
61
|
+
set(state => ({
|
|
62
|
+
events: { ...state.events,
|
|
63
|
+
connected
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
const handlers = connected.getEventHandlers();
|
|
67
|
+
return handlers;
|
|
68
|
+
},
|
|
69
|
+
disconnect: () => {
|
|
70
|
+
const {
|
|
71
|
+
set,
|
|
72
|
+
events
|
|
73
|
+
} = store.getState();
|
|
74
|
+
|
|
75
|
+
if (events.connected) {
|
|
76
|
+
events.connected.reset();
|
|
77
|
+
set(state => ({
|
|
78
|
+
events: { ...state.events,
|
|
79
|
+
connected: false
|
|
80
|
+
}
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'orthographic', 'frameloop', 'performance', 'clock', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
|
|
88
|
+
|
|
89
|
+
function Block({
|
|
90
|
+
set
|
|
91
|
+
}) {
|
|
92
|
+
React.useLayoutEffect(() => {
|
|
93
|
+
set(new Promise(() => null));
|
|
94
|
+
return () => set(false);
|
|
95
|
+
}, [set]);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
class ErrorBoundary extends React.Component {
|
|
100
|
+
constructor(...args) {
|
|
101
|
+
super(...args);
|
|
102
|
+
this.state = {
|
|
103
|
+
error: false
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
componentDidCatch(error) {
|
|
108
|
+
this.props.set(error);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
render() {
|
|
112
|
+
return this.state.error ? null : this.props.children;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
ErrorBoundary.getDerivedStateFromError = () => ({
|
|
118
|
+
error: true
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const Canvas = /*#__PURE__*/React.forwardRef(({
|
|
122
|
+
children,
|
|
123
|
+
fallback,
|
|
124
|
+
style,
|
|
125
|
+
events,
|
|
126
|
+
...props
|
|
127
|
+
}, forwardedRef) => {
|
|
128
|
+
// Create a known catalogue of Threejs-native elements
|
|
129
|
+
// This will include the entire THREE namespace by default, users can extend
|
|
130
|
+
// their own elements by using the createRoot API instead
|
|
131
|
+
React.useMemo(() => extend(THREE), []);
|
|
132
|
+
const [{
|
|
133
|
+
width,
|
|
134
|
+
height
|
|
135
|
+
}, setSize] = React.useState({
|
|
136
|
+
width: 0,
|
|
137
|
+
height: 0
|
|
138
|
+
});
|
|
139
|
+
const [canvas, setCanvas] = React.useState(null);
|
|
140
|
+
const [bind, setBind] = React.useState();
|
|
141
|
+
const canvasProps = pick(props, CANVAS_PROPS);
|
|
142
|
+
const viewProps = omit(props, CANVAS_PROPS);
|
|
143
|
+
const [block, setBlock] = React.useState(false);
|
|
144
|
+
const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
|
|
145
|
+
|
|
146
|
+
if (block) throw block; // Throw exception outwards if anything within canvas throws
|
|
147
|
+
|
|
148
|
+
if (error) throw error;
|
|
149
|
+
const onLayout = React.useCallback(e => {
|
|
150
|
+
const {
|
|
151
|
+
width,
|
|
152
|
+
height
|
|
153
|
+
} = e.nativeEvent.layout;
|
|
154
|
+
setSize({
|
|
155
|
+
width,
|
|
156
|
+
height
|
|
157
|
+
});
|
|
158
|
+
}, []);
|
|
159
|
+
const onContextCreate = React.useCallback(context => {
|
|
160
|
+
const canvasShim = {
|
|
161
|
+
width: context.drawingBufferWidth,
|
|
162
|
+
height: context.drawingBufferHeight,
|
|
163
|
+
style: {},
|
|
164
|
+
addEventListener: () => {},
|
|
165
|
+
removeEventListener: () => {},
|
|
166
|
+
clientHeight: context.drawingBufferHeight,
|
|
167
|
+
getContext: () => context
|
|
168
|
+
};
|
|
169
|
+
setCanvas(canvasShim);
|
|
170
|
+
}, []);
|
|
171
|
+
|
|
172
|
+
if (width > 0 && height > 0 && canvas) {
|
|
173
|
+
// Overwrite onCreated to apply RN bindings
|
|
174
|
+
const onCreated = state => {
|
|
175
|
+
// Bind events after creation
|
|
176
|
+
const handlers = state.events.connect == null ? void 0 : state.events.connect(canvas);
|
|
177
|
+
setBind(handlers); // Bind render to RN bridge
|
|
178
|
+
|
|
179
|
+
const context = state.gl.getContext();
|
|
180
|
+
const renderFrame = state.gl.render.bind(state.gl);
|
|
181
|
+
|
|
182
|
+
state.gl.render = (scene, camera) => {
|
|
183
|
+
renderFrame(scene, camera);
|
|
184
|
+
context.endFrameEXP();
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
return canvasProps == null ? void 0 : canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
createRoot(canvas, { ...canvasProps,
|
|
191
|
+
// expo-gl can only render at native dpr/resolution
|
|
192
|
+
// https://github.com/expo/expo-three/issues/39
|
|
193
|
+
dpr: PixelRatio.get(),
|
|
194
|
+
size: {
|
|
195
|
+
width,
|
|
196
|
+
height
|
|
197
|
+
},
|
|
198
|
+
events: events || createTouchEvents,
|
|
199
|
+
onCreated
|
|
200
|
+
}).render( /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
201
|
+
set: setError
|
|
202
|
+
}, /*#__PURE__*/React.createElement(React.Suspense, {
|
|
203
|
+
fallback: /*#__PURE__*/React.createElement(Block, {
|
|
204
|
+
set: setBlock
|
|
205
|
+
})
|
|
206
|
+
}, children)));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
React.useEffect(() => {
|
|
210
|
+
return () => unmountComponentAtNode(canvas);
|
|
211
|
+
}, [canvas]);
|
|
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
|
+
onContextCreate: onContextCreate,
|
|
221
|
+
style: StyleSheet.absoluteFill
|
|
222
|
+
}));
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Generates an asset based on input type.
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
const getAsset = input => {
|
|
230
|
+
if (input instanceof Asset) return input;
|
|
231
|
+
|
|
232
|
+
switch (typeof input) {
|
|
233
|
+
case 'string':
|
|
234
|
+
return Asset.fromURI(input);
|
|
235
|
+
|
|
236
|
+
case 'number':
|
|
237
|
+
return Asset.fromModule(input);
|
|
238
|
+
|
|
239
|
+
default:
|
|
240
|
+
throw 'Invalid asset! Must be a URI or module.';
|
|
241
|
+
}
|
|
242
|
+
}; // Don't pre-process urls, let expo-asset generate an absolute URL
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
THREE.LoaderUtils.extractUrlBase = () => './'; // There's no Image in native, so create a data texture instead
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
THREE.TextureLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
|
|
249
|
+
const texture = new THREE.Texture(); // @ts-expect-error
|
|
250
|
+
|
|
251
|
+
texture.isDataTexture = true;
|
|
252
|
+
getAsset(url).downloadAsync().then(asset => {
|
|
253
|
+
texture.image = {
|
|
254
|
+
data: asset,
|
|
255
|
+
width: asset.width,
|
|
256
|
+
height: asset.height
|
|
257
|
+
};
|
|
258
|
+
texture.needsUpdate = true;
|
|
259
|
+
onLoad == null ? void 0 : onLoad(texture);
|
|
260
|
+
}).catch(onError);
|
|
261
|
+
return texture;
|
|
262
|
+
}; // Fetches assets via XMLHttpRequest
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
THREE.FileLoader.prototype.load = function (url, onLoad, onProgress, onError) {
|
|
266
|
+
if (this.path) url = this.path + url;
|
|
267
|
+
const request = new XMLHttpRequest();
|
|
268
|
+
getAsset(url).downloadAsync().then(asset => {
|
|
269
|
+
request.open('GET', asset.uri, true);
|
|
270
|
+
request.addEventListener('load', event => {
|
|
271
|
+
if (request.status === 200) {
|
|
272
|
+
onLoad == null ? void 0 : onLoad(request.response);
|
|
273
|
+
this.manager.itemEnd(url);
|
|
274
|
+
} else {
|
|
275
|
+
onError == null ? void 0 : onError(event);
|
|
276
|
+
this.manager.itemError(url);
|
|
277
|
+
this.manager.itemEnd(url);
|
|
278
|
+
}
|
|
279
|
+
}, false);
|
|
280
|
+
request.addEventListener('progress', event => {
|
|
281
|
+
onProgress == null ? void 0 : onProgress(event);
|
|
282
|
+
}, false);
|
|
283
|
+
request.addEventListener('error', event => {
|
|
284
|
+
onError == null ? void 0 : onError(event);
|
|
285
|
+
this.manager.itemError(url);
|
|
286
|
+
this.manager.itemEnd(url);
|
|
287
|
+
}, false);
|
|
288
|
+
request.addEventListener('abort', event => {
|
|
289
|
+
onError == null ? void 0 : onError(event);
|
|
290
|
+
this.manager.itemError(url);
|
|
291
|
+
this.manager.itemEnd(url);
|
|
292
|
+
}, false);
|
|
293
|
+
if (this.responseType) request.responseType = this.responseType;
|
|
294
|
+
if (this.withCredentials) request.withCredentials = this.withCredentials;
|
|
295
|
+
|
|
296
|
+
for (const header in this.requestHeader) {
|
|
297
|
+
request.setRequestHeader(header, this.requestHeader[header]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
request.send(null);
|
|
301
|
+
this.manager.itemStart(url);
|
|
302
|
+
});
|
|
303
|
+
return request;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export { Canvas, createTouchEvents as events };
|