@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.
@@ -5,7 +5,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var THREE = require('three');
6
6
  var React = require('react');
7
7
  var create = require('zustand');
8
- var shallow = require('zustand/shallow');
9
8
  var Reconciler = require('react-reconciler');
10
9
  var scheduler = require('scheduler');
11
10
  var useAsset = require('use-asset');
@@ -37,7 +36,6 @@ function _interopNamespace(e) {
37
36
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
38
37
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
39
38
  var create__default = /*#__PURE__*/_interopDefault(create);
40
- var shallow__default = /*#__PURE__*/_interopDefault(shallow);
41
39
  var Reconciler__default = /*#__PURE__*/_interopDefault(Reconciler);
42
40
  var mergeRefs__default = /*#__PURE__*/_interopDefault(mergeRefs);
43
41
  var useMeasure__default = /*#__PURE__*/_interopDefault(useMeasure);
@@ -76,6 +74,23 @@ const is = {
76
74
  function makeId(event) {
77
75
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
78
76
  }
77
+ /** Release pointer captures.
78
+ * This is called by releasePointerCapture in the API, and when an object is removed.
79
+ */
80
+
81
+
82
+ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
83
+ const captureData = captures.get(obj);
84
+
85
+ if (captureData) {
86
+ captures.delete(obj); // If this was the last capturing object for this pointer
87
+
88
+ if (captures.size === 0) {
89
+ capturedMap.delete(pointerId);
90
+ captureData.target.releasePointerCapture(pointerId);
91
+ }
92
+ }
93
+ }
79
94
 
80
95
  function removeInteractivity(store, object) {
81
96
  const {
@@ -89,6 +104,9 @@ function removeInteractivity(store, object) {
89
104
  internal.hovered.delete(key);
90
105
  }
91
106
  });
107
+ internal.capturedMap.forEach((captures, pointerId) => {
108
+ releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
109
+ });
92
110
  }
93
111
  function createEvents(store) {
94
112
  const temp = new THREE__namespace.Vector3();
@@ -168,7 +186,7 @@ function createEvents(store) {
168
186
  while (eventObject) {
169
187
  var _r3f2;
170
188
 
171
- if ((_r3f2 = eventObject.__r3f) != null && _r3f2.handlers.count) intersections.push({ ...intersect,
189
+ if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...intersect,
172
190
  eventObject
173
191
  });
174
192
  eventObject = eventObject.parent;
@@ -187,7 +205,9 @@ function createEvents(store) {
187
205
  // intersect.
188
206
 
189
207
  if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
190
- intersections.push(...internal.capturedMap.get(event.pointerId).values());
208
+ for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
209
+ intersections.push(captureData.intersection);
210
+ }
191
211
  }
192
212
 
193
213
  return intersections;
@@ -205,9 +225,6 @@ function createEvents(store) {
205
225
 
206
226
  if (intersections.length) {
207
227
  const unprojectedPoint = temp.set(mouse.x, mouse.y, 0).unproject(camera);
208
-
209
- const releasePointerCapture = id => event.target.releasePointerCapture(id);
210
-
211
228
  const localState = {
212
229
  stopped: false
213
230
  };
@@ -220,23 +237,36 @@ function createEvents(store) {
220
237
  };
221
238
 
222
239
  const setPointerCapture = id => {
240
+ const captureData = {
241
+ intersection: hit,
242
+ target: event.target
243
+ };
244
+
223
245
  if (internal.capturedMap.has(id)) {
224
246
  // if the pointerId was previously captured, we add the hit to the
225
247
  // event capturedMap.
226
- internal.capturedMap.get(id).set(hit.eventObject, hit);
248
+ internal.capturedMap.get(id).set(hit.eventObject, captureData);
227
249
  } else {
228
250
  // if the pointerId was not previously captured, we create a map
229
251
  // containing the hitObject, and the hit. hitObject is used for
230
252
  // faster access.
231
- internal.capturedMap.set(id, new Map([[hit.eventObject, hit]]));
253
+ internal.capturedMap.set(id, new Map([[hit.eventObject, captureData]]));
232
254
  } // Call the original event now
233
255
  event.target.setPointerCapture(id);
256
+ };
257
+
258
+ const releasePointerCapture = id => {
259
+ const captures = internal.capturedMap.get(id);
260
+
261
+ if (captures) {
262
+ releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
263
+ }
234
264
  }; // Add native event props
235
265
 
236
266
 
237
- let extractEventProps = {};
267
+ 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.
238
268
 
239
- for (let prop in Object.getPrototypeOf(event)) {
269
+ for (let prop in event) {
240
270
  let property = event[prop]; // Only copy over atomics, leave functions alone as these should be
241
271
  // called as event.nativeEvent.fn()
242
272
 
@@ -305,13 +335,12 @@ function createEvents(store) {
305
335
  // When no objects were hit or the the hovered object wasn't found underneath the cursor
306
336
  // we call onPointerOut and delete the object from the hovered-elements map
307
337
  if (!hits.length || !hits.find(hit => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId)) {
308
- var _r3f3;
309
-
310
338
  const eventObject = hoveredObj.eventObject;
311
- const handlers = (_r3f3 = eventObject.__r3f) == null ? void 0 : _r3f3.handlers;
339
+ const instance = eventObject.__r3f;
340
+ const handlers = instance == null ? void 0 : instance.handlers;
312
341
  internal.hovered.delete(makeId(hoveredObj));
313
342
 
314
- if (handlers != null && handlers.count) {
343
+ if (instance != null && instance.eventCount) {
315
344
  // Clear out intersects, they are outdated by now
316
345
  const data = { ...hoveredObj,
317
346
  intersections: hits || []
@@ -333,9 +362,8 @@ function createEvents(store) {
333
362
  case 'onLostPointerCapture':
334
363
  return event => {
335
364
  if ('pointerId' in event) {
336
- // this will be a problem if one target releases the pointerId
337
- // and another one is still keeping it, as the line below
338
- // indifferently deletes all capturing references.
365
+ // If the object event interface had onLostPointerCapture, we'd call it here on every
366
+ // object that's getting removed.
339
367
  store.getState().internal.capturedMap.delete(event.pointerId);
340
368
  }
341
369
 
@@ -374,12 +402,11 @@ function createEvents(store) {
374
402
 
375
403
  if (isPointerMove) cancelPointer(hits);
376
404
  handleIntersects(hits, event, delta, data => {
377
- var _r3f4;
378
-
379
405
  const eventObject = data.eventObject;
380
- const handlers = (_r3f4 = eventObject.__r3f) == null ? void 0 : _r3f4.handlers; // Check presence of handlers
406
+ const instance = eventObject.__r3f;
407
+ const handlers = instance == null ? void 0 : instance.handlers; // Check presence of handlers
381
408
 
382
- if (!(handlers != null && handlers.count)) return;
409
+ if (!(instance != null && instance.eventCount)) return;
383
410
 
384
411
  if (isPointerMove) {
385
412
  // Move event ...
@@ -422,9 +449,9 @@ function createEvents(store) {
422
449
 
423
450
  function pointerMissed(event, objects) {
424
451
  objects.forEach(object => {
425
- var _r3f5;
452
+ var _r3f3;
426
453
 
427
- return (_r3f5 = object.__r3f) == null ? void 0 : _r3f5.handlers.onPointerMissed == null ? void 0 : _r3f5.handlers.onPointerMissed(event);
454
+ return (_r3f3 = object.__r3f) == null ? void 0 : _r3f3.handlers.onPointerMissed == null ? void 0 : _r3f3.handlers.onPointerMissed(event);
428
455
  });
429
456
  }
430
457
 
@@ -475,9 +502,8 @@ function prepare(object, state) {
475
502
  instance.__r3f = {
476
503
  root: null,
477
504
  memoizedProps: {},
478
- handlers: {
479
- count: 0
480
- },
505
+ eventCount: 0,
506
+ handlers: {},
481
507
  objects: [],
482
508
  parent: null,
483
509
  ...state
@@ -538,7 +564,7 @@ function createRenderer(roots) {
538
564
  }
539
565
 
540
566
  function applyProps(instance, data) {
541
- var _instance$__r3f3, _root$getState, _localState$handlers, _localState$handlers2, _instance$__r3f4;
567
+ var _instance$__r3f3, _root$getState, _instance$__r3f4;
542
568
 
543
569
  // Filter equals, events and reserved props
544
570
  const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {};
@@ -548,7 +574,7 @@ function createRenderer(roots) {
548
574
  memoized,
549
575
  changes
550
576
  } = isDiffSet(data) ? data : diffProps(instance, data);
551
- const prevHandlers = (_localState$handlers = localState.handlers) == null ? void 0 : _localState$handlers.count; // Prepare memoized props
577
+ const prevHandlers = localState.eventCount; // Prepare memoized props
552
578
 
553
579
  if (instance.__r3f) instance.__r3f.memoizedProps = memoized;
554
580
  changes.forEach(([key, value, isEvent, keys]) => {
@@ -587,7 +613,7 @@ function createRenderer(roots) {
587
613
 
588
614
  if (isEvent) {
589
615
  if (value) localState.handlers[key] = value;else delete localState.handlers[key];
590
- localState.handlers.count = Object.keys(localState.handlers).length;
616
+ localState.eventCount = Object.keys(localState.handlers).length;
591
617
  } // Special treatment for objects with support for set/copy, and layers
592
618
  else if (targetProp && targetProp.set && (targetProp.copy || targetProp instanceof THREE__namespace.Layers)) {
593
619
  // If value is an array
@@ -595,21 +621,21 @@ function createRenderer(roots) {
595
621
  if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
596
622
  } // Test again target.copy(class) next ...
597
623
  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
598
- // https://github.com/react-spring/react-three-fiber/issues/274
624
+ // https://github.com/pmndrs/react-three-fiber/issues/274
599
625
  else if (value !== undefined) {
600
626
  const isColor = targetProp instanceof THREE__namespace.Color; // Allow setting array scalars
601
627
 
602
628
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
603
629
  else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
604
630
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
605
- // https://github.com/react-spring/react-three-fiber/issues/344
631
+ // https://github.com/pmndrs/react-three-fiber/issues/344
606
632
 
607
633
  if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
608
634
  } // Else, just overwrite the value
609
635
 
610
636
  } else {
611
637
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
612
- // https://github.com/react-spring/react-three-fiber/issues/344
638
+ // https://github.com/pmndrs/react-three-fiber/issues/344
613
639
 
614
640
  if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
615
641
  }
@@ -617,12 +643,12 @@ function createRenderer(roots) {
617
643
  invalidateInstance(instance);
618
644
  });
619
645
 
620
- if (rootState.internal && instance.raycast && prevHandlers !== ((_localState$handlers2 = localState.handlers) == null ? void 0 : _localState$handlers2.count)) {
646
+ if (rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
621
647
  // Pre-emptively remove the instance from the interaction manager
622
648
  const index = rootState.internal.interaction.indexOf(instance);
623
649
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
624
650
 
625
- if (localState.handlers.count) rootState.internal.interaction.push(instance);
651
+ if (localState.eventCount) rootState.internal.interaction.push(instance);
626
652
  } // Call the update lifecycle when it is being updated
627
653
 
628
654
 
@@ -813,7 +839,7 @@ function createRenderer(roots) {
813
839
  } else if (is.fun(detachFn)) {
814
840
  detachFn(child, parentInstance);
815
841
  }
816
- } else if (child.isObject3D) {
842
+ } else if (child.isObject3D && parentInstance.isObject3D) {
817
843
  var _child$__r3f;
818
844
 
819
845
  parentInstance.remove(child); // Remove interactivity
@@ -1059,11 +1085,11 @@ const createStore = (applyProps, invalidate, advance, props) => {
1059
1085
  if (shadows) {
1060
1086
  gl.shadowMap.enabled = true;
1061
1087
  if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE__namespace.PCFSoftShadowMap;
1062
- } // Set color management
1088
+ } // Set color preferences
1063
1089
 
1064
1090
 
1065
- if (!linear) gl.outputEncoding = THREE__namespace.sRGBEncoding;
1066
- if (!flat) gl.toneMapping = THREE__namespace.ACESFilmicToneMapping; // clock.elapsedTime is updated using advance(timestamp)
1091
+ if (linear) gl.outputEncoding = THREE__namespace.LinearEncoding;
1092
+ if (flat) gl.toneMapping = THREE__namespace.NoToneMapping; // clock.elapsedTime is updated using advance(timestamp)
1067
1093
 
1068
1094
  if (frameloop === 'never') {
1069
1095
  clock.stop();
@@ -1252,38 +1278,45 @@ const createStore = (applyProps, invalidate, advance, props) => {
1252
1278
  }
1253
1279
  }
1254
1280
  };
1255
- }); // Resize camera and renderer on changes to size and pixelratio
1281
+ });
1282
+ const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
1256
1283
 
1284
+ let oldSize = state.size;
1285
+ let oldDpr = state.viewport.dpr;
1257
1286
  rootState.subscribe(() => {
1258
1287
  const {
1259
1288
  camera,
1260
1289
  size,
1261
1290
  viewport,
1262
1291
  internal
1263
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1264
- // Do not mess with the camera if it belongs to the user
1265
-
1266
- if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1267
- if (isOrthographicCamera(camera)) {
1268
- camera.left = size.width / -2;
1269
- camera.right = size.width / 2;
1270
- camera.top = size.height / 2;
1271
- camera.bottom = size.height / -2;
1272
- } else {
1273
- camera.aspect = size.width / size.height;
1274
- }
1292
+ } = rootState.getState();
1293
+
1294
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1295
+ // https://github.com/pmndrs/react-three-fiber/issues/92
1296
+ // Do not mess with the camera if it belongs to the user
1297
+ if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1298
+ if (isOrthographicCamera(camera)) {
1299
+ camera.left = size.width / -2;
1300
+ camera.right = size.width / 2;
1301
+ camera.top = size.height / 2;
1302
+ camera.bottom = size.height / -2;
1303
+ } else {
1304
+ camera.aspect = size.width / size.height;
1305
+ }
1275
1306
 
1276
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1277
- // Update matrix world since the renderer is a frame late
1307
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1308
+ // Update matrix world since the renderer is a frame late
1278
1309
 
1279
- camera.updateMatrixWorld();
1280
- } // Update renderer
1310
+ camera.updateMatrixWorld();
1311
+ } // Update renderer
1281
1312
 
1282
1313
 
1283
- gl.setPixelRatio(viewport.dpr);
1284
- gl.setSize(size.width, size.height);
1285
- }, state => [state.viewport.dpr, state.size], shallow__default['default']);
1286
- const state = rootState.getState(); // Update size
1314
+ gl.setPixelRatio(viewport.dpr);
1315
+ gl.setSize(size.width, size.height);
1316
+ oldSize = size;
1317
+ oldDpr = viewport.dpr;
1318
+ }
1319
+ }); // Update size
1287
1320
 
1288
1321
  if (size) state.setSize(size.width, size.height); // Invalidate on any change
1289
1322
 
@@ -1647,7 +1680,11 @@ const createRendererInstance = (gl, canvas) => {
1647
1680
  antialias: true,
1648
1681
  alpha: true,
1649
1682
  ...gl
1650
- });
1683
+ }); // Set color management
1684
+
1685
+ renderer.outputEncoding = THREE__namespace.sRGBEncoding;
1686
+ renderer.toneMapping = THREE__namespace.ACESFilmicToneMapping; // Set gl props
1687
+
1651
1688
  if (gl) applyProps(renderer, gl);
1652
1689
  return renderer;
1653
1690
  };