@react-three/fiber 7.0.18 → 7.0.22

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.
@@ -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';
@@ -345,7 +344,8 @@ function createEvents(store) {
345
344
  onPointerMissed,
346
345
  internal
347
346
  } = store.getState();
348
- prepareRay(event); // Get fresh intersects
347
+ prepareRay(event);
348
+ internal.lastEvent.current = event; // Get fresh intersects
349
349
 
350
350
  const isPointerMove = name === 'onPointerMove';
351
351
  const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
@@ -403,12 +403,17 @@ function createEvents(store) {
403
403
  if (handler) {
404
404
  // Forward all events back to their respective handlers with the exception of click events,
405
405
  // which must use the initial target
406
- if (name !== 'onClick' && name !== 'onContextMenu' && name !== 'onDoubleClick' || internal.initialHits.includes(eventObject)) {
406
+ if (!isClickEvent || internal.initialHits.includes(eventObject)) {
407
407
  // Missed events have to come first
408
408
  pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object))); // Now call the handler
409
409
 
410
410
  handler(data);
411
411
  }
412
+ } else {
413
+ // Trigger onPointerMissed on all elements that have pointer over/out handlers, but not click and weren't hit
414
+ if (isClickEvent && internal.initialHits.includes(eventObject)) {
415
+ pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object)));
416
+ }
412
417
  }
413
418
  }
414
419
  });
@@ -589,21 +594,21 @@ function createRenderer(roots) {
589
594
  if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
590
595
  } // Test again target.copy(class) next ...
591
596
  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
592
- // https://github.com/react-spring/react-three-fiber/issues/274
597
+ // https://github.com/pmndrs/react-three-fiber/issues/274
593
598
  else if (value !== undefined) {
594
599
  const isColor = targetProp instanceof THREE.Color; // Allow setting array scalars
595
600
 
596
601
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
597
602
  else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
598
603
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
599
- // https://github.com/react-spring/react-three-fiber/issues/344
604
+ // https://github.com/pmndrs/react-three-fiber/issues/344
600
605
 
601
606
  if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
602
607
  } // Else, just overwrite the value
603
608
 
604
609
  } else {
605
610
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
606
- // https://github.com/react-spring/react-three-fiber/issues/344
611
+ // https://github.com/pmndrs/react-three-fiber/issues/344
607
612
 
608
613
  if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) currentInstance[key].encoding = THREE.sRGBEncoding;
609
614
  }
@@ -611,7 +616,7 @@ function createRenderer(roots) {
611
616
  invalidateInstance(instance);
612
617
  });
613
618
 
614
- if (rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
619
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
615
620
  // Pre-emptively remove the instance from the interaction manager
616
621
  const index = rootState.internal.interaction.indexOf(instance);
617
622
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -664,7 +669,9 @@ function createRenderer(roots) {
664
669
  });
665
670
  } else {
666
671
  const target = catalogue[name] || THREE[name];
667
- if (!target) throw `${name} is not part of the THREE namespace! Did you forget to extend? See: https://github.com/pmndrs/react-three-fiber/blob/master/markdown/api.md#using-3rd-party-objects-declaratively`; // Instanciate new object, link it to the root
672
+ if (!target) throw `${name} is not part of the THREE namespace! Did you forget to extend? See: https://github.com/pmndrs/react-three-fiber/blob/master/markdown/api.md#using-3rd-party-objects-declaratively`; // Throw if an object or literal was passed for args
673
+
674
+ if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
668
675
  // Append memoized props with args so it's not forgotten
669
676
 
670
677
  instance = prepare(new target(...args), {
@@ -938,7 +945,9 @@ function createRenderer(roots) {
938
945
  args: argsOld = [],
939
946
  children: cO,
940
947
  ...restOld
941
- } = oldProps; // If it has new props or arguments, then it needs to be re-instanciated
948
+ } = oldProps; // Throw if an object or literal was passed for args
949
+
950
+ if (!Array.isArray(argsNew)) throw 'The args prop must be an array!'; // If it has new props or arguments, then it needs to be re-instanciated
942
951
 
943
952
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
944
953
 
@@ -988,11 +997,24 @@ function createRenderer(roots) {
988
997
 
989
998
  createTextInstance() {},
990
999
 
991
- finalizeInitialChildren() {
992
- return false;
1000
+ finalizeInitialChildren(instance) {
1001
+ var _instance$__r3f7;
1002
+
1003
+ // https://github.com/facebook/react/issues/20271
1004
+ // Returning true will trigger commitMount
1005
+ const localState = (_instance$__r3f7 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f7 : {};
1006
+ return !!localState.handlers;
993
1007
  },
994
1008
 
995
- commitMount() {// noop
1009
+ commitMount(instance)
1010
+ /*, type, props*/
1011
+ {
1012
+ var _instance$__r3f8;
1013
+
1014
+ // https://github.com/facebook/react/issues/20271
1015
+ // This will make sure events are only added once to the central container
1016
+ const localState = (_instance$__r3f8 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f8 : {};
1017
+ if (instance.raycast && localState.handlers && localState.eventCount) instance.__r3f.root.getState().internal.interaction.push(instance);
996
1018
  },
997
1019
 
998
1020
  shouldDeprioritizeSubtree() {
@@ -1199,6 +1221,9 @@ const createStore = (applyProps, invalidate, advance, props) => {
1199
1221
  dpr: calculateDpr(dpr)
1200
1222
  }
1201
1223
  })),
1224
+ setFrameloop: (frameloop = 'always') => set(() => ({
1225
+ frameloop
1226
+ })),
1202
1227
  events: {
1203
1228
  connected: false
1204
1229
  },
@@ -1207,6 +1232,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
1207
1232
  priority: 0,
1208
1233
  frames: 0,
1209
1234
  lastProps: props,
1235
+ lastEvent: /*#__PURE__*/React.createRef(),
1210
1236
  interaction: [],
1211
1237
  hovered: new Map(),
1212
1238
  subscribers: [],
@@ -1246,38 +1272,47 @@ const createStore = (applyProps, invalidate, advance, props) => {
1246
1272
  }
1247
1273
  }
1248
1274
  };
1249
- }); // Resize camera and renderer on changes to size and pixelratio
1275
+ });
1276
+ const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
1250
1277
 
1278
+ let oldSize = state.size;
1279
+ let oldDpr = state.viewport.dpr;
1251
1280
  rootState.subscribe(() => {
1252
1281
  const {
1253
1282
  camera,
1254
1283
  size,
1255
1284
  viewport,
1256
1285
  internal
1257
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1258
- // Do not mess with the camera if it belongs to the user
1259
-
1260
- if (!(internal.lastProps.camera instanceof THREE.Camera)) {
1261
- if (isOrthographicCamera(camera)) {
1262
- camera.left = size.width / -2;
1263
- camera.right = size.width / 2;
1264
- camera.top = size.height / 2;
1265
- camera.bottom = size.height / -2;
1266
- } else {
1267
- camera.aspect = size.width / size.height;
1268
- }
1286
+ } = rootState.getState();
1287
+
1288
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1289
+ // https://github.com/pmndrs/react-three-fiber/issues/92
1290
+ // Do not mess with the camera if it belongs to the user
1291
+ if (!camera.manual && !(internal.lastProps.camera instanceof THREE.Camera)) {
1292
+ console.log('update camera');
1293
+
1294
+ if (isOrthographicCamera(camera)) {
1295
+ camera.left = size.width / -2;
1296
+ camera.right = size.width / 2;
1297
+ camera.top = size.height / 2;
1298
+ camera.bottom = size.height / -2;
1299
+ } else {
1300
+ camera.aspect = size.width / size.height;
1301
+ }
1269
1302
 
1270
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1271
- // Update matrix world since the renderer is a frame late
1303
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1304
+ // Update matrix world since the renderer is a frame late
1272
1305
 
1273
- camera.updateMatrixWorld();
1274
- } // Update renderer
1306
+ camera.updateMatrixWorld();
1307
+ } // Update renderer
1275
1308
 
1276
1309
 
1277
- gl.setPixelRatio(viewport.dpr);
1278
- gl.setSize(size.width, size.height);
1279
- }, state => [state.viewport.dpr, state.size], shallow);
1280
- const state = rootState.getState(); // Update size
1310
+ gl.setPixelRatio(viewport.dpr);
1311
+ gl.setSize(size.width, size.height);
1312
+ oldSize = size;
1313
+ oldDpr = viewport.dpr;
1314
+ }
1315
+ }); // Update size
1281
1316
 
1282
1317
  if (size) state.setSize(size.width, size.height); // Invalidate on any change
1283
1318
 
@@ -1680,7 +1715,9 @@ function render(element, canvas, {
1680
1715
  // Check pixelratio
1681
1716
  if (props.dpr !== undefined && !is.equ(state.viewport.dpr, calculateDpr(props.dpr))) state.setDpr(props.dpr); // Check size
1682
1717
 
1683
- if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // For some props we want to reset the entire root
1718
+ if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // Check frameloop
1719
+
1720
+ if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
1684
1721
  // Changes to the color-space
1685
1722
 
1686
1723
  const linearChanged = props.linear !== state.internal.lastProps.linear;
@@ -0,0 +1 @@
1
+ export * from "../../dist/declarations/src/native";