@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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 7.0.22
4
+
5
+ ### Patch Changes
6
+
7
+ - 259e1fa: add camera:manual
8
+
9
+ ## 7.0.21
10
+
11
+ ### Patch Changes
12
+
13
+ - 65e4147: up usemeasure, add last event to internals"
14
+
15
+ ## 7.0.20
16
+
17
+ ### Patch Changes
18
+
19
+ - 54cb0fd: update react-use-measure, allow it to use the offsetSize
20
+
21
+ ## 7.0.19
22
+
23
+ ### Patch Changes
24
+
25
+ - 7aa2eab: fix: remove zustand subcribe selector
26
+
3
27
  ## 7.0.18
4
28
 
5
29
  ### Patch Changes
@@ -4,7 +4,7 @@ import type { RootState } from './store';
4
4
  export interface Intersection extends THREE.Intersection {
5
5
  eventObject: THREE.Object3D;
6
6
  }
7
- export interface IntesectionEvent<TSourceEvent> extends Intersection {
7
+ export interface IntersectionEvent<TSourceEvent> extends Intersection {
8
8
  intersections: Intersection[];
9
9
  stopped: boolean;
10
10
  unprojectedPoint: THREE.Vector3;
@@ -18,8 +18,8 @@ export interface IntesectionEvent<TSourceEvent> extends Intersection {
18
18
  spaceY: number;
19
19
  }
20
20
  export declare type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera;
21
- export declare type ThreeEvent<TEvent> = TEvent & IntesectionEvent<TEvent>;
22
- export declare type DomEvent = ThreeEvent<PointerEvent | MouseEvent | WheelEvent>;
21
+ export declare type ThreeEvent<TEvent> = IntersectionEvent<TEvent>;
22
+ export declare type DomEvent = PointerEvent | MouseEvent | WheelEvent;
23
23
  export declare type Events = {
24
24
  onClick: EventListener;
25
25
  onContextMenu: EventListener;
@@ -43,7 +43,7 @@ export declare type EventHandlers = {
43
43
  onPointerEnter?: (event: ThreeEvent<PointerEvent>) => void;
44
44
  onPointerLeave?: (event: ThreeEvent<PointerEvent>) => void;
45
45
  onPointerMove?: (event: ThreeEvent<PointerEvent>) => void;
46
- onPointerMissed?: (event: ThreeEvent<PointerEvent>) => void;
46
+ onPointerMissed?: (event: MouseEvent) => void;
47
47
  onPointerCancel?: (event: ThreeEvent<PointerEvent>) => void;
48
48
  onWheel?: (event: ThreeEvent<WheelEvent>) => void;
49
49
  };
@@ -47,8 +47,9 @@ export declare type InternalState = {
47
47
  priority: number;
48
48
  frames: number;
49
49
  lastProps: StoreProps;
50
+ lastEvent: React.MutableRefObject<DomEvent | null>;
50
51
  interaction: THREE.Object3D[];
51
- hovered: Map<string, DomEvent>;
52
+ hovered: Map<string, ThreeEvent<DomEvent>>;
52
53
  subscribers: Subscription[];
53
54
  capturedMap: Map<number, Map<THREE.Object3D, PointerCaptureTarget>>;
54
55
  initialClick: [x: number, y: number];
@@ -58,7 +59,9 @@ export declare type InternalState = {
58
59
  export declare type RootState = {
59
60
  gl: THREE.WebGLRenderer;
60
61
  scene: THREE.Scene;
61
- camera: Camera;
62
+ camera: Camera & {
63
+ manual?: boolean;
64
+ };
62
65
  controls: THREE.EventDispatcher | null;
63
66
  raycaster: Raycaster;
64
67
  mouse: THREE.Vector2;
@@ -78,7 +81,8 @@ export declare type RootState = {
78
81
  advance: (timestamp: number, runGlobalEffects?: boolean) => void;
79
82
  setSize: (width: number, height: number) => void;
80
83
  setDpr: (dpr: Dpr) => void;
81
- onPointerMissed?: (event: ThreeEvent<PointerEvent>) => void;
84
+ setFrameloop: (frameloop?: 'always' | 'demand' | 'never') => void;
85
+ onPointerMissed?: (event: MouseEvent) => void;
82
86
  events: EventManager<any>;
83
87
  internal: InternalState;
84
88
  };
@@ -100,8 +104,10 @@ export declare type StoreProps = {
100
104
  dpr?: Dpr;
101
105
  clock?: THREE.Clock;
102
106
  raycaster?: Partial<Raycaster>;
103
- camera?: Camera | Partial<ReactThreeFiber.Object3DNode<THREE.Camera, typeof THREE.Camera> & ReactThreeFiber.Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera> & ReactThreeFiber.Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>>;
104
- onPointerMissed?: (event: ThreeEvent<PointerEvent>) => void;
107
+ camera?: (Camera | Partial<ReactThreeFiber.Object3DNode<THREE.Camera, typeof THREE.Camera> & ReactThreeFiber.Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera> & ReactThreeFiber.Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>>) & {
108
+ manual?: boolean;
109
+ };
110
+ onPointerMissed?: (event: MouseEvent) => void;
105
111
  };
106
112
  export declare type ApplyProps = (instance: Instance, newProps: InstanceProps) => void;
107
113
  export declare function calculateDpr(dpr: Dpr): number;
@@ -23,7 +23,7 @@ export interface NodeProps<T, P> {
23
23
  attachFns?: [AttachCallback, AttachCallback];
24
24
  args?: Args<P>;
25
25
  children?: React.ReactNode;
26
- ref?: React.Ref<React.ReactNode>;
26
+ ref?: React.RefCallback<T> | React.RefObject<React.ReactNode> | null;
27
27
  key?: React.Key;
28
28
  onUpdate?: (self: T) => void;
29
29
  }
@@ -59,7 +59,6 @@ export declare type LineSegmentsProps = Object3DNode<THREE.LineSegments, typeof
59
59
  export declare type LineLoopProps = Object3DNode<THREE.LineLoop, typeof THREE.LineLoop>;
60
60
  export declare type PointsProps = Object3DNode<THREE.Points, typeof THREE.Points>;
61
61
  export declare type GroupProps = Object3DNode<THREE.Group, typeof THREE.Group>;
62
- export declare type ImmediateRenderObjectProps = Object3DNode<THREE.ImmediateRenderObject, typeof THREE.ImmediateRenderObject>;
63
62
  export declare type CameraProps = Object3DNode<THREE.Camera, typeof THREE.Camera>;
64
63
  export declare type PerspectiveCameraProps = Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera>;
65
64
  export declare type OrthographicCameraProps = Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>;
@@ -175,6 +174,7 @@ export declare type Matrix3Props = Node<THREE.Matrix3, typeof THREE.Matrix3>;
175
174
  export declare type Matrix4Props = Node<THREE.Matrix4, typeof THREE.Matrix4>;
176
175
  export declare type QuaternionProps = Node<THREE.Quaternion, typeof THREE.Quaternion>;
177
176
  export declare type BufferAttributeProps = Node<THREE.BufferAttribute, typeof THREE.BufferAttribute>;
177
+ export declare type Float32BufferAttributeProps = Node<THREE.Float32BufferAttribute, typeof THREE.Float32BufferAttribute>;
178
178
  export declare type InstancedBufferAttributeProps = Node<THREE.InstancedBufferAttribute, typeof THREE.InstancedBufferAttribute>;
179
179
  export declare type ColorProps = Node<THREE.Color, ColorArray>;
180
180
  export declare type FogProps = Node<THREE.Fog, typeof THREE.Fog>;
@@ -197,7 +197,6 @@ declare global {
197
197
  lineLoop: LineLoopProps;
198
198
  points: PointsProps;
199
199
  group: GroupProps;
200
- immediateRenderObject: ImmediateRenderObjectProps;
201
200
  camera: CameraProps;
202
201
  perspectiveCamera: PerspectiveCameraProps;
203
202
  orthographicCamera: OrthographicCameraProps;
@@ -309,6 +308,7 @@ declare global {
309
308
  matrix4: Matrix4Props;
310
309
  quaternion: QuaternionProps;
311
310
  bufferAttribute: BufferAttributeProps;
311
+ float32BufferAttribute: Float32BufferAttributeProps;
312
312
  instancedBufferAttribute: InstancedBufferAttributeProps;
313
313
  color: ColorProps;
314
314
  fog: FogProps;
@@ -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);
@@ -379,7 +377,8 @@ function createEvents(store) {
379
377
  onPointerMissed,
380
378
  internal
381
379
  } = store.getState();
382
- prepareRay(event); // Get fresh intersects
380
+ prepareRay(event);
381
+ internal.lastEvent.current = event; // Get fresh intersects
383
382
 
384
383
  const isPointerMove = name === 'onPointerMove';
385
384
  const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
@@ -437,12 +436,17 @@ function createEvents(store) {
437
436
  if (handler) {
438
437
  // Forward all events back to their respective handlers with the exception of click events,
439
438
  // which must use the initial target
440
- if (name !== 'onClick' && name !== 'onContextMenu' && name !== 'onDoubleClick' || internal.initialHits.includes(eventObject)) {
439
+ if (!isClickEvent || internal.initialHits.includes(eventObject)) {
441
440
  // Missed events have to come first
442
441
  pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object))); // Now call the handler
443
442
 
444
443
  handler(data);
445
444
  }
445
+ } else {
446
+ // Trigger onPointerMissed on all elements that have pointer over/out handlers, but not click and weren't hit
447
+ if (isClickEvent && internal.initialHits.includes(eventObject)) {
448
+ pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object)));
449
+ }
446
450
  }
447
451
  }
448
452
  });
@@ -623,21 +627,21 @@ function createRenderer(roots) {
623
627
  if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
624
628
  } // Test again target.copy(class) next ...
625
629
  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
626
- // https://github.com/react-spring/react-three-fiber/issues/274
630
+ // https://github.com/pmndrs/react-three-fiber/issues/274
627
631
  else if (value !== undefined) {
628
632
  const isColor = targetProp instanceof THREE__namespace.Color; // Allow setting array scalars
629
633
 
630
634
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
631
635
  else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
632
636
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
633
- // https://github.com/react-spring/react-three-fiber/issues/344
637
+ // https://github.com/pmndrs/react-three-fiber/issues/344
634
638
 
635
639
  if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
636
640
  } // Else, just overwrite the value
637
641
 
638
642
  } else {
639
643
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
640
- // https://github.com/react-spring/react-three-fiber/issues/344
644
+ // https://github.com/pmndrs/react-three-fiber/issues/344
641
645
 
642
646
  if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
643
647
  }
@@ -645,7 +649,7 @@ function createRenderer(roots) {
645
649
  invalidateInstance(instance);
646
650
  });
647
651
 
648
- if (rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
652
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
649
653
  // Pre-emptively remove the instance from the interaction manager
650
654
  const index = rootState.internal.interaction.indexOf(instance);
651
655
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -698,7 +702,9 @@ function createRenderer(roots) {
698
702
  });
699
703
  } else {
700
704
  const target = catalogue[name] || THREE__namespace[name];
701
- 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
705
+ 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
706
+
707
+ if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
702
708
  // Append memoized props with args so it's not forgotten
703
709
 
704
710
  instance = prepare(new target(...args), {
@@ -972,7 +978,9 @@ function createRenderer(roots) {
972
978
  args: argsOld = [],
973
979
  children: cO,
974
980
  ...restOld
975
- } = oldProps; // If it has new props or arguments, then it needs to be re-instanciated
981
+ } = oldProps; // Throw if an object or literal was passed for args
982
+
983
+ 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
976
984
 
977
985
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
978
986
 
@@ -1022,11 +1030,24 @@ function createRenderer(roots) {
1022
1030
 
1023
1031
  createTextInstance() {},
1024
1032
 
1025
- finalizeInitialChildren() {
1026
- return false;
1033
+ finalizeInitialChildren(instance) {
1034
+ var _instance$__r3f7;
1035
+
1036
+ // https://github.com/facebook/react/issues/20271
1037
+ // Returning true will trigger commitMount
1038
+ const localState = (_instance$__r3f7 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f7 : {};
1039
+ return !!localState.handlers;
1027
1040
  },
1028
1041
 
1029
- commitMount() {// noop
1042
+ commitMount(instance)
1043
+ /*, type, props*/
1044
+ {
1045
+ var _instance$__r3f8;
1046
+
1047
+ // https://github.com/facebook/react/issues/20271
1048
+ // This will make sure events are only added once to the central container
1049
+ const localState = (_instance$__r3f8 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f8 : {};
1050
+ if (instance.raycast && localState.handlers && localState.eventCount) instance.__r3f.root.getState().internal.interaction.push(instance);
1030
1051
  },
1031
1052
 
1032
1053
  shouldDeprioritizeSubtree() {
@@ -1233,6 +1254,9 @@ const createStore = (applyProps, invalidate, advance, props) => {
1233
1254
  dpr: calculateDpr(dpr)
1234
1255
  }
1235
1256
  })),
1257
+ setFrameloop: (frameloop = 'always') => set(() => ({
1258
+ frameloop
1259
+ })),
1236
1260
  events: {
1237
1261
  connected: false
1238
1262
  },
@@ -1241,6 +1265,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
1241
1265
  priority: 0,
1242
1266
  frames: 0,
1243
1267
  lastProps: props,
1268
+ lastEvent: /*#__PURE__*/React__namespace.createRef(),
1244
1269
  interaction: [],
1245
1270
  hovered: new Map(),
1246
1271
  subscribers: [],
@@ -1280,38 +1305,47 @@ const createStore = (applyProps, invalidate, advance, props) => {
1280
1305
  }
1281
1306
  }
1282
1307
  };
1283
- }); // Resize camera and renderer on changes to size and pixelratio
1308
+ });
1309
+ const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
1284
1310
 
1311
+ let oldSize = state.size;
1312
+ let oldDpr = state.viewport.dpr;
1285
1313
  rootState.subscribe(() => {
1286
1314
  const {
1287
1315
  camera,
1288
1316
  size,
1289
1317
  viewport,
1290
1318
  internal
1291
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1292
- // Do not mess with the camera if it belongs to the user
1293
-
1294
- if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1295
- if (isOrthographicCamera(camera)) {
1296
- camera.left = size.width / -2;
1297
- camera.right = size.width / 2;
1298
- camera.top = size.height / 2;
1299
- camera.bottom = size.height / -2;
1300
- } else {
1301
- camera.aspect = size.width / size.height;
1302
- }
1319
+ } = rootState.getState();
1320
+
1321
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1322
+ // https://github.com/pmndrs/react-three-fiber/issues/92
1323
+ // Do not mess with the camera if it belongs to the user
1324
+ if (!camera.manual && !(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1325
+ console.log('update camera');
1326
+
1327
+ if (isOrthographicCamera(camera)) {
1328
+ camera.left = size.width / -2;
1329
+ camera.right = size.width / 2;
1330
+ camera.top = size.height / 2;
1331
+ camera.bottom = size.height / -2;
1332
+ } else {
1333
+ camera.aspect = size.width / size.height;
1334
+ }
1303
1335
 
1304
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1305
- // Update matrix world since the renderer is a frame late
1336
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1337
+ // Update matrix world since the renderer is a frame late
1306
1338
 
1307
- camera.updateMatrixWorld();
1308
- } // Update renderer
1339
+ camera.updateMatrixWorld();
1340
+ } // Update renderer
1309
1341
 
1310
1342
 
1311
- gl.setPixelRatio(viewport.dpr);
1312
- gl.setSize(size.width, size.height);
1313
- }, state => [state.viewport.dpr, state.size], shallow__default['default']);
1314
- const state = rootState.getState(); // Update size
1343
+ gl.setPixelRatio(viewport.dpr);
1344
+ gl.setSize(size.width, size.height);
1345
+ oldSize = size;
1346
+ oldDpr = viewport.dpr;
1347
+ }
1348
+ }); // Update size
1315
1349
 
1316
1350
  if (size) state.setSize(size.width, size.height); // Invalidate on any change
1317
1351
 
@@ -1714,7 +1748,9 @@ function render(element, canvas, {
1714
1748
  // Check pixelratio
1715
1749
  if (props.dpr !== undefined && !is.equ(state.viewport.dpr, calculateDpr(props.dpr))) state.setDpr(props.dpr); // Check size
1716
1750
 
1717
- 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
1751
+ if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // Check frameloop
1752
+
1753
+ if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
1718
1754
  // Changes to the color-space
1719
1755
 
1720
1756
  const linearChanged = props.linear !== state.internal.lastProps.linear;
@@ -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);
@@ -379,7 +377,8 @@ function createEvents(store) {
379
377
  onPointerMissed,
380
378
  internal
381
379
  } = store.getState();
382
- prepareRay(event); // Get fresh intersects
380
+ prepareRay(event);
381
+ internal.lastEvent.current = event; // Get fresh intersects
383
382
 
384
383
  const isPointerMove = name === 'onPointerMove';
385
384
  const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
@@ -437,12 +436,17 @@ function createEvents(store) {
437
436
  if (handler) {
438
437
  // Forward all events back to their respective handlers with the exception of click events,
439
438
  // which must use the initial target
440
- if (name !== 'onClick' && name !== 'onContextMenu' && name !== 'onDoubleClick' || internal.initialHits.includes(eventObject)) {
439
+ if (!isClickEvent || internal.initialHits.includes(eventObject)) {
441
440
  // Missed events have to come first
442
441
  pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object))); // Now call the handler
443
442
 
444
443
  handler(data);
445
444
  }
445
+ } else {
446
+ // Trigger onPointerMissed on all elements that have pointer over/out handlers, but not click and weren't hit
447
+ if (isClickEvent && internal.initialHits.includes(eventObject)) {
448
+ pointerMissed(event, internal.interaction.filter(object => !internal.initialHits.includes(object)));
449
+ }
446
450
  }
447
451
  }
448
452
  });
@@ -623,21 +627,21 @@ function createRenderer(roots) {
623
627
  if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
624
628
  } // Test again target.copy(class) next ...
625
629
  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
626
- // https://github.com/react-spring/react-three-fiber/issues/274
630
+ // https://github.com/pmndrs/react-three-fiber/issues/274
627
631
  else if (value !== undefined) {
628
632
  const isColor = targetProp instanceof THREE__namespace.Color; // Allow setting array scalars
629
633
 
630
634
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
631
635
  else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
632
636
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
633
- // https://github.com/react-spring/react-three-fiber/issues/344
637
+ // https://github.com/pmndrs/react-three-fiber/issues/344
634
638
 
635
639
  if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
636
640
  } // Else, just overwrite the value
637
641
 
638
642
  } else {
639
643
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
640
- // https://github.com/react-spring/react-three-fiber/issues/344
644
+ // https://github.com/pmndrs/react-three-fiber/issues/344
641
645
 
642
646
  if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
643
647
  }
@@ -645,7 +649,7 @@ function createRenderer(roots) {
645
649
  invalidateInstance(instance);
646
650
  });
647
651
 
648
- if (rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
652
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
649
653
  // Pre-emptively remove the instance from the interaction manager
650
654
  const index = rootState.internal.interaction.indexOf(instance);
651
655
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -698,7 +702,9 @@ function createRenderer(roots) {
698
702
  });
699
703
  } else {
700
704
  const target = catalogue[name] || THREE__namespace[name];
701
- 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
705
+ 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
706
+
707
+ if (!Array.isArray(args)) throw 'The args prop must be an array!'; // Instanciate new object, link it to the root
702
708
  // Append memoized props with args so it's not forgotten
703
709
 
704
710
  instance = prepare(new target(...args), {
@@ -972,7 +978,9 @@ function createRenderer(roots) {
972
978
  args: argsOld = [],
973
979
  children: cO,
974
980
  ...restOld
975
- } = oldProps; // If it has new props or arguments, then it needs to be re-instanciated
981
+ } = oldProps; // Throw if an object or literal was passed for args
982
+
983
+ 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
976
984
 
977
985
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
978
986
 
@@ -1022,11 +1030,24 @@ function createRenderer(roots) {
1022
1030
 
1023
1031
  createTextInstance() {},
1024
1032
 
1025
- finalizeInitialChildren() {
1026
- return false;
1033
+ finalizeInitialChildren(instance) {
1034
+ var _instance$__r3f7;
1035
+
1036
+ // https://github.com/facebook/react/issues/20271
1037
+ // Returning true will trigger commitMount
1038
+ const localState = (_instance$__r3f7 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f7 : {};
1039
+ return !!localState.handlers;
1027
1040
  },
1028
1041
 
1029
- commitMount() {// noop
1042
+ commitMount(instance)
1043
+ /*, type, props*/
1044
+ {
1045
+ var _instance$__r3f8;
1046
+
1047
+ // https://github.com/facebook/react/issues/20271
1048
+ // This will make sure events are only added once to the central container
1049
+ const localState = (_instance$__r3f8 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f8 : {};
1050
+ if (instance.raycast && localState.handlers && localState.eventCount) instance.__r3f.root.getState().internal.interaction.push(instance);
1030
1051
  },
1031
1052
 
1032
1053
  shouldDeprioritizeSubtree() {
@@ -1233,6 +1254,9 @@ const createStore = (applyProps, invalidate, advance, props) => {
1233
1254
  dpr: calculateDpr(dpr)
1234
1255
  }
1235
1256
  })),
1257
+ setFrameloop: (frameloop = 'always') => set(() => ({
1258
+ frameloop
1259
+ })),
1236
1260
  events: {
1237
1261
  connected: false
1238
1262
  },
@@ -1241,6 +1265,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
1241
1265
  priority: 0,
1242
1266
  frames: 0,
1243
1267
  lastProps: props,
1268
+ lastEvent: /*#__PURE__*/React__namespace.createRef(),
1244
1269
  interaction: [],
1245
1270
  hovered: new Map(),
1246
1271
  subscribers: [],
@@ -1280,38 +1305,47 @@ const createStore = (applyProps, invalidate, advance, props) => {
1280
1305
  }
1281
1306
  }
1282
1307
  };
1283
- }); // Resize camera and renderer on changes to size and pixelratio
1308
+ });
1309
+ const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
1284
1310
 
1311
+ let oldSize = state.size;
1312
+ let oldDpr = state.viewport.dpr;
1285
1313
  rootState.subscribe(() => {
1286
1314
  const {
1287
1315
  camera,
1288
1316
  size,
1289
1317
  viewport,
1290
1318
  internal
1291
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1292
- // Do not mess with the camera if it belongs to the user
1293
-
1294
- if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1295
- if (isOrthographicCamera(camera)) {
1296
- camera.left = size.width / -2;
1297
- camera.right = size.width / 2;
1298
- camera.top = size.height / 2;
1299
- camera.bottom = size.height / -2;
1300
- } else {
1301
- camera.aspect = size.width / size.height;
1302
- }
1319
+ } = rootState.getState();
1320
+
1321
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1322
+ // https://github.com/pmndrs/react-three-fiber/issues/92
1323
+ // Do not mess with the camera if it belongs to the user
1324
+ if (!camera.manual && !(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1325
+ console.log('update camera');
1326
+
1327
+ if (isOrthographicCamera(camera)) {
1328
+ camera.left = size.width / -2;
1329
+ camera.right = size.width / 2;
1330
+ camera.top = size.height / 2;
1331
+ camera.bottom = size.height / -2;
1332
+ } else {
1333
+ camera.aspect = size.width / size.height;
1334
+ }
1303
1335
 
1304
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1305
- // Update matrix world since the renderer is a frame late
1336
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1337
+ // Update matrix world since the renderer is a frame late
1306
1338
 
1307
- camera.updateMatrixWorld();
1308
- } // Update renderer
1339
+ camera.updateMatrixWorld();
1340
+ } // Update renderer
1309
1341
 
1310
1342
 
1311
- gl.setPixelRatio(viewport.dpr);
1312
- gl.setSize(size.width, size.height);
1313
- }, state => [state.viewport.dpr, state.size], shallow__default['default']);
1314
- const state = rootState.getState(); // Update size
1343
+ gl.setPixelRatio(viewport.dpr);
1344
+ gl.setSize(size.width, size.height);
1345
+ oldSize = size;
1346
+ oldDpr = viewport.dpr;
1347
+ }
1348
+ }); // Update size
1315
1349
 
1316
1350
  if (size) state.setSize(size.width, size.height); // Invalidate on any change
1317
1351
 
@@ -1714,7 +1748,9 @@ function render(element, canvas, {
1714
1748
  // Check pixelratio
1715
1749
  if (props.dpr !== undefined && !is.equ(state.viewport.dpr, calculateDpr(props.dpr))) state.setDpr(props.dpr); // Check size
1716
1750
 
1717
- 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
1751
+ if (state.size.width !== size.width || state.size.height !== size.height) state.setSize(size.width, size.height); // Check frameloop
1752
+
1753
+ if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
1718
1754
  // Changes to the color-space
1719
1755
 
1720
1756
  const linearChanged = props.linear !== state.internal.lastProps.linear;