@react-three/fiber 7.0.16 → 7.0.20
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 +24 -0
- package/dist/declarations/src/core/events.d.ts +4 -0
- package/dist/declarations/src/core/renderer.d.ts +2 -3
- package/dist/declarations/src/core/store.d.ts +2 -2
- package/dist/declarations/src/three-types.d.ts +0 -2
- package/dist/react-three-fiber.cjs.dev.js +98 -61
- package/dist/react-three-fiber.cjs.prod.js +98 -61
- package/dist/react-three-fiber.esm.js +98 -60
- package/native/dist/react-three-fiber-native.cjs.d.ts +1 -0
- package/native/dist/react-three-fiber-native.cjs.dev.js +590 -0
- package/native/dist/react-three-fiber-native.cjs.js +7 -0
- package/native/dist/react-three-fiber-native.cjs.prod.js +590 -0
- package/native/dist/react-three-fiber-native.esm.js +538 -0
- package/package.json +2 -2
- package/readme.md +10 -10
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import create from 'zustand';
|
|
4
|
-
import shallow from 'zustand/shallow';
|
|
5
4
|
import Reconciler from 'react-reconciler';
|
|
6
5
|
import { unstable_now, unstable_runWithPriority, unstable_IdlePriority } from 'scheduler';
|
|
7
6
|
import { useAsset } from 'use-asset';
|
|
@@ -42,6 +41,23 @@ const is = {
|
|
|
42
41
|
function makeId(event) {
|
|
43
42
|
return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
|
|
44
43
|
}
|
|
44
|
+
/** Release pointer captures.
|
|
45
|
+
* This is called by releasePointerCapture in the API, and when an object is removed.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
50
|
+
const captureData = captures.get(obj);
|
|
51
|
+
|
|
52
|
+
if (captureData) {
|
|
53
|
+
captures.delete(obj); // If this was the last capturing object for this pointer
|
|
54
|
+
|
|
55
|
+
if (captures.size === 0) {
|
|
56
|
+
capturedMap.delete(pointerId);
|
|
57
|
+
captureData.target.releasePointerCapture(pointerId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
45
61
|
|
|
46
62
|
function removeInteractivity(store, object) {
|
|
47
63
|
const {
|
|
@@ -55,6 +71,9 @@ function removeInteractivity(store, object) {
|
|
|
55
71
|
internal.hovered.delete(key);
|
|
56
72
|
}
|
|
57
73
|
});
|
|
74
|
+
internal.capturedMap.forEach((captures, pointerId) => {
|
|
75
|
+
releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
|
|
76
|
+
});
|
|
58
77
|
}
|
|
59
78
|
function createEvents(store) {
|
|
60
79
|
const temp = new THREE.Vector3();
|
|
@@ -134,7 +153,7 @@ function createEvents(store) {
|
|
|
134
153
|
while (eventObject) {
|
|
135
154
|
var _r3f2;
|
|
136
155
|
|
|
137
|
-
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.
|
|
156
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...intersect,
|
|
138
157
|
eventObject
|
|
139
158
|
});
|
|
140
159
|
eventObject = eventObject.parent;
|
|
@@ -153,7 +172,9 @@ function createEvents(store) {
|
|
|
153
172
|
// intersect.
|
|
154
173
|
|
|
155
174
|
if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
|
|
156
|
-
|
|
175
|
+
for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
|
|
176
|
+
intersections.push(captureData.intersection);
|
|
177
|
+
}
|
|
157
178
|
}
|
|
158
179
|
|
|
159
180
|
return intersections;
|
|
@@ -171,9 +192,6 @@ function createEvents(store) {
|
|
|
171
192
|
|
|
172
193
|
if (intersections.length) {
|
|
173
194
|
const unprojectedPoint = temp.set(mouse.x, mouse.y, 0).unproject(camera);
|
|
174
|
-
|
|
175
|
-
const releasePointerCapture = id => event.target.releasePointerCapture(id);
|
|
176
|
-
|
|
177
195
|
const localState = {
|
|
178
196
|
stopped: false
|
|
179
197
|
};
|
|
@@ -186,23 +204,36 @@ function createEvents(store) {
|
|
|
186
204
|
};
|
|
187
205
|
|
|
188
206
|
const setPointerCapture = id => {
|
|
207
|
+
const captureData = {
|
|
208
|
+
intersection: hit,
|
|
209
|
+
target: event.target
|
|
210
|
+
};
|
|
211
|
+
|
|
189
212
|
if (internal.capturedMap.has(id)) {
|
|
190
213
|
// if the pointerId was previously captured, we add the hit to the
|
|
191
214
|
// event capturedMap.
|
|
192
|
-
internal.capturedMap.get(id).set(hit.eventObject,
|
|
215
|
+
internal.capturedMap.get(id).set(hit.eventObject, captureData);
|
|
193
216
|
} else {
|
|
194
217
|
// if the pointerId was not previously captured, we create a map
|
|
195
218
|
// containing the hitObject, and the hit. hitObject is used for
|
|
196
219
|
// faster access.
|
|
197
|
-
internal.capturedMap.set(id, new Map([[hit.eventObject,
|
|
220
|
+
internal.capturedMap.set(id, new Map([[hit.eventObject, captureData]]));
|
|
198
221
|
} // Call the original event now
|
|
199
222
|
event.target.setPointerCapture(id);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const releasePointerCapture = id => {
|
|
226
|
+
const captures = internal.capturedMap.get(id);
|
|
227
|
+
|
|
228
|
+
if (captures) {
|
|
229
|
+
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
230
|
+
}
|
|
200
231
|
}; // Add native event props
|
|
201
232
|
|
|
202
233
|
|
|
203
|
-
let extractEventProps = {};
|
|
234
|
+
let extractEventProps = {}; // This iterates over the event's properties including the inherited ones. Native PointerEvents have most of their props as getters which are inherited, but polyfilled PointerEvents have them all as their own properties (i.e. not inherited). We can't use Object.keys() or Object.entries() as they only return "own" properties; nor Object.getPrototypeOf(event) as that *doesn't* return "own" properties, only inherited ones.
|
|
204
235
|
|
|
205
|
-
for (let prop in
|
|
236
|
+
for (let prop in event) {
|
|
206
237
|
let property = event[prop]; // Only copy over atomics, leave functions alone as these should be
|
|
207
238
|
// called as event.nativeEvent.fn()
|
|
208
239
|
|
|
@@ -271,13 +302,12 @@ function createEvents(store) {
|
|
|
271
302
|
// When no objects were hit or the the hovered object wasn't found underneath the cursor
|
|
272
303
|
// we call onPointerOut and delete the object from the hovered-elements map
|
|
273
304
|
if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId)) {
|
|
274
|
-
var _r3f3;
|
|
275
|
-
|
|
276
305
|
const eventObject = hoveredObj.eventObject;
|
|
277
|
-
const
|
|
306
|
+
const instance = eventObject.__r3f;
|
|
307
|
+
const handlers = instance == null ? void 0 : instance.handlers;
|
|
278
308
|
internal.hovered.delete(makeId(hoveredObj));
|
|
279
309
|
|
|
280
|
-
if (
|
|
310
|
+
if (instance != null && instance.eventCount) {
|
|
281
311
|
// Clear out intersects, they are outdated by now
|
|
282
312
|
const data = { ...hoveredObj,
|
|
283
313
|
intersections: hits || []
|
|
@@ -299,9 +329,8 @@ function createEvents(store) {
|
|
|
299
329
|
case 'onLostPointerCapture':
|
|
300
330
|
return event => {
|
|
301
331
|
if ('pointerId' in event) {
|
|
302
|
-
//
|
|
303
|
-
//
|
|
304
|
-
// indifferently deletes all capturing references.
|
|
332
|
+
// If the object event interface had onLostPointerCapture, we'd call it here on every
|
|
333
|
+
// object that's getting removed.
|
|
305
334
|
store.getState().internal.capturedMap.delete(event.pointerId);
|
|
306
335
|
}
|
|
307
336
|
|
|
@@ -340,12 +369,11 @@ function createEvents(store) {
|
|
|
340
369
|
|
|
341
370
|
if (isPointerMove) cancelPointer(hits);
|
|
342
371
|
handleIntersects(hits, event, delta, data => {
|
|
343
|
-
var _r3f4;
|
|
344
|
-
|
|
345
372
|
const eventObject = data.eventObject;
|
|
346
|
-
const
|
|
373
|
+
const instance = eventObject.__r3f;
|
|
374
|
+
const handlers = instance == null ? void 0 : instance.handlers; // Check presence of handlers
|
|
347
375
|
|
|
348
|
-
if (!(
|
|
376
|
+
if (!(instance != null && instance.eventCount)) return;
|
|
349
377
|
|
|
350
378
|
if (isPointerMove) {
|
|
351
379
|
// Move event ...
|
|
@@ -388,9 +416,9 @@ function createEvents(store) {
|
|
|
388
416
|
|
|
389
417
|
function pointerMissed(event, objects) {
|
|
390
418
|
objects.forEach(object => {
|
|
391
|
-
var
|
|
419
|
+
var _r3f3;
|
|
392
420
|
|
|
393
|
-
return (
|
|
421
|
+
return (_r3f3 = object.__r3f) == null ? void 0 : _r3f3.handlers.onPointerMissed == null ? void 0 : _r3f3.handlers.onPointerMissed(event);
|
|
394
422
|
});
|
|
395
423
|
}
|
|
396
424
|
|
|
@@ -441,9 +469,8 @@ function prepare(object, state) {
|
|
|
441
469
|
instance.__r3f = {
|
|
442
470
|
root: null,
|
|
443
471
|
memoizedProps: {},
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
},
|
|
472
|
+
eventCount: 0,
|
|
473
|
+
handlers: {},
|
|
447
474
|
objects: [],
|
|
448
475
|
parent: null,
|
|
449
476
|
...state
|
|
@@ -504,7 +531,7 @@ function createRenderer(roots) {
|
|
|
504
531
|
}
|
|
505
532
|
|
|
506
533
|
function applyProps(instance, data) {
|
|
507
|
-
var _instance$__r3f3, _root$getState,
|
|
534
|
+
var _instance$__r3f3, _root$getState, _instance$__r3f4;
|
|
508
535
|
|
|
509
536
|
// Filter equals, events and reserved props
|
|
510
537
|
const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {};
|
|
@@ -514,7 +541,7 @@ function createRenderer(roots) {
|
|
|
514
541
|
memoized,
|
|
515
542
|
changes
|
|
516
543
|
} = isDiffSet(data) ? data : diffProps(instance, data);
|
|
517
|
-
const prevHandlers =
|
|
544
|
+
const prevHandlers = localState.eventCount; // Prepare memoized props
|
|
518
545
|
|
|
519
546
|
if (instance.__r3f) instance.__r3f.memoizedProps = memoized;
|
|
520
547
|
changes.forEach(([key, value, isEvent, keys]) => {
|
|
@@ -553,7 +580,7 @@ function createRenderer(roots) {
|
|
|
553
580
|
|
|
554
581
|
if (isEvent) {
|
|
555
582
|
if (value) localState.handlers[key] = value;else delete localState.handlers[key];
|
|
556
|
-
localState.
|
|
583
|
+
localState.eventCount = Object.keys(localState.handlers).length;
|
|
557
584
|
} // Special treatment for objects with support for set/copy, and layers
|
|
558
585
|
else if (targetProp && targetProp.set && (targetProp.copy || targetProp instanceof THREE.Layers)) {
|
|
559
586
|
// If value is an array
|
|
@@ -561,21 +588,21 @@ function createRenderer(roots) {
|
|
|
561
588
|
if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
|
|
562
589
|
} // Test again target.copy(class) next ...
|
|
563
590
|
else if (targetProp.copy && value && value.constructor && targetProp.constructor.name === value.constructor.name) targetProp.copy(value); // If nothing else fits, just set the single value, ignore undefined
|
|
564
|
-
// https://github.com/
|
|
591
|
+
// https://github.com/pmndrs/react-three-fiber/issues/274
|
|
565
592
|
else if (value !== undefined) {
|
|
566
593
|
const isColor = targetProp instanceof THREE.Color; // Allow setting array scalars
|
|
567
594
|
|
|
568
595
|
if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
|
|
569
596
|
else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
|
|
570
597
|
else targetProp.set(value); // Auto-convert sRGB colors, for now ...
|
|
571
|
-
// https://github.com/
|
|
598
|
+
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
572
599
|
|
|
573
600
|
if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
|
|
574
601
|
} // Else, just overwrite the value
|
|
575
602
|
|
|
576
603
|
} else {
|
|
577
604
|
currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
|
|
578
|
-
// https://github.com/
|
|
605
|
+
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
579
606
|
|
|
580
607
|
if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) currentInstance[key].encoding = THREE.sRGBEncoding;
|
|
581
608
|
}
|
|
@@ -583,12 +610,12 @@ function createRenderer(roots) {
|
|
|
583
610
|
invalidateInstance(instance);
|
|
584
611
|
});
|
|
585
612
|
|
|
586
|
-
if (rootState.internal && instance.raycast && prevHandlers !==
|
|
613
|
+
if (rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
|
|
587
614
|
// Pre-emptively remove the instance from the interaction manager
|
|
588
615
|
const index = rootState.internal.interaction.indexOf(instance);
|
|
589
616
|
if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
|
|
590
617
|
|
|
591
|
-
if (localState.
|
|
618
|
+
if (localState.eventCount) rootState.internal.interaction.push(instance);
|
|
592
619
|
} // Call the update lifecycle when it is being updated
|
|
593
620
|
|
|
594
621
|
|
|
@@ -779,7 +806,7 @@ function createRenderer(roots) {
|
|
|
779
806
|
} else if (is.fun(detachFn)) {
|
|
780
807
|
detachFn(child, parentInstance);
|
|
781
808
|
}
|
|
782
|
-
} else if (child.isObject3D) {
|
|
809
|
+
} else if (child.isObject3D && parentInstance.isObject3D) {
|
|
783
810
|
var _child$__r3f;
|
|
784
811
|
|
|
785
812
|
parentInstance.remove(child); // Remove interactivity
|
|
@@ -1025,11 +1052,11 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1025
1052
|
if (shadows) {
|
|
1026
1053
|
gl.shadowMap.enabled = true;
|
|
1027
1054
|
if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
1028
|
-
} // Set color
|
|
1055
|
+
} // Set color preferences
|
|
1029
1056
|
|
|
1030
1057
|
|
|
1031
|
-
if (
|
|
1032
|
-
if (
|
|
1058
|
+
if (linear) gl.outputEncoding = THREE.LinearEncoding;
|
|
1059
|
+
if (flat) gl.toneMapping = THREE.NoToneMapping; // clock.elapsedTime is updated using advance(timestamp)
|
|
1033
1060
|
|
|
1034
1061
|
if (frameloop === 'never') {
|
|
1035
1062
|
clock.stop();
|
|
@@ -1218,38 +1245,45 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1218
1245
|
}
|
|
1219
1246
|
}
|
|
1220
1247
|
};
|
|
1221
|
-
});
|
|
1248
|
+
});
|
|
1249
|
+
const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
|
|
1222
1250
|
|
|
1251
|
+
let oldSize = state.size;
|
|
1252
|
+
let oldDpr = state.viewport.dpr;
|
|
1223
1253
|
rootState.subscribe(() => {
|
|
1224
1254
|
const {
|
|
1225
1255
|
camera,
|
|
1226
1256
|
size,
|
|
1227
1257
|
viewport,
|
|
1228
1258
|
internal
|
|
1229
|
-
} = rootState.getState();
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
camera
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1259
|
+
} = rootState.getState();
|
|
1260
|
+
|
|
1261
|
+
if (size !== oldSize || viewport.dpr !== oldDpr) {
|
|
1262
|
+
// https://github.com/pmndrs/react-three-fiber/issues/92
|
|
1263
|
+
// Do not mess with the camera if it belongs to the user
|
|
1264
|
+
if (!(internal.lastProps.camera instanceof THREE.Camera)) {
|
|
1265
|
+
if (isOrthographicCamera(camera)) {
|
|
1266
|
+
camera.left = size.width / -2;
|
|
1267
|
+
camera.right = size.width / 2;
|
|
1268
|
+
camera.top = size.height / 2;
|
|
1269
|
+
camera.bottom = size.height / -2;
|
|
1270
|
+
} else {
|
|
1271
|
+
camera.aspect = size.width / size.height;
|
|
1272
|
+
}
|
|
1241
1273
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1274
|
+
camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
|
|
1275
|
+
// Update matrix world since the renderer is a frame late
|
|
1244
1276
|
|
|
1245
|
-
|
|
1246
|
-
|
|
1277
|
+
camera.updateMatrixWorld();
|
|
1278
|
+
} // Update renderer
|
|
1247
1279
|
|
|
1248
1280
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1281
|
+
gl.setPixelRatio(viewport.dpr);
|
|
1282
|
+
gl.setSize(size.width, size.height);
|
|
1283
|
+
oldSize = size;
|
|
1284
|
+
oldDpr = viewport.dpr;
|
|
1285
|
+
}
|
|
1286
|
+
}); // Update size
|
|
1253
1287
|
|
|
1254
1288
|
if (size) state.setSize(size.width, size.height); // Invalidate on any change
|
|
1255
1289
|
|
|
@@ -1613,7 +1647,11 @@ const createRendererInstance = (gl, canvas) => {
|
|
|
1613
1647
|
antialias: true,
|
|
1614
1648
|
alpha: true,
|
|
1615
1649
|
...gl
|
|
1616
|
-
});
|
|
1650
|
+
}); // Set color management
|
|
1651
|
+
|
|
1652
|
+
renderer.outputEncoding = THREE.sRGBEncoding;
|
|
1653
|
+
renderer.toneMapping = THREE.ACESFilmicToneMapping; // Set gl props
|
|
1654
|
+
|
|
1617
1655
|
if (gl) applyProps(renderer, gl);
|
|
1618
1656
|
return renderer;
|
|
1619
1657
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../dist/declarations/src/native";
|