@react-three/fiber 9.0.0-rc.5 → 9.0.0-rc.7

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +1088 -1076
  2. package/dist/declarations/src/core/events.d.ts +91 -91
  3. package/dist/declarations/src/core/hooks.d.ts +51 -51
  4. package/dist/declarations/src/core/index.d.ts +13 -13
  5. package/dist/declarations/src/core/loop.d.ts +31 -31
  6. package/dist/declarations/src/core/reconciler.d.ts +50 -52
  7. package/dist/declarations/src/core/renderer.d.ts +89 -89
  8. package/dist/declarations/src/core/store.d.ts +130 -130
  9. package/dist/declarations/src/core/utils.d.ts +186 -186
  10. package/dist/declarations/src/index.d.ts +6 -6
  11. package/dist/declarations/src/native/Canvas.d.ts +13 -13
  12. package/dist/declarations/src/native/events.d.ts +4 -4
  13. package/dist/declarations/src/native.d.ts +6 -6
  14. package/dist/declarations/src/three-types.d.ts +66 -62
  15. package/dist/declarations/src/web/Canvas.d.ts +23 -23
  16. package/dist/declarations/src/web/events.d.ts +4 -4
  17. package/dist/{events-a7b08b1a.esm.js → events-12fa3319.esm.js} +138 -118
  18. package/dist/{events-b4061ace.cjs.dev.js → events-56f909a9.cjs.dev.js} +138 -118
  19. package/dist/{events-60ed2d7b.cjs.prod.js → events-858f07e7.cjs.prod.js} +138 -118
  20. package/dist/react-three-fiber.cjs.dev.js +7 -201
  21. package/dist/react-three-fiber.cjs.prod.js +7 -201
  22. package/dist/react-three-fiber.esm.js +6 -201
  23. package/native/dist/react-three-fiber-native.cjs.d.ts +2 -0
  24. package/native/dist/react-three-fiber-native.cjs.dev.js +554 -0
  25. package/native/dist/react-three-fiber-native.cjs.js +7 -0
  26. package/native/dist/react-three-fiber-native.cjs.prod.js +554 -0
  27. package/native/dist/react-three-fiber-native.esm.js +502 -0
  28. package/native/package.json +5 -5
  29. package/package.json +87 -88
  30. package/readme.md +253 -253
  31. package/dist/declarations/src/web/use-measure.d.ts +0 -34
@@ -38,29 +38,29 @@ var threeTypes = /*#__PURE__*/Object.freeze({
38
38
  __proto__: null
39
39
  });
40
40
 
41
- /**
42
- * Returns the instance's initial (outmost) root.
41
+ /**
42
+ * Returns the instance's initial (outmost) root.
43
43
  */
44
44
  function findInitialRoot(instance) {
45
45
  let root = instance.root;
46
46
  while (root.getState().previousRoot) root = root.getState().previousRoot;
47
47
  return root;
48
48
  }
49
- /**
50
- * Safely flush async effects when testing, simulating a legacy root.
49
+ /**
50
+ * Safely flush async effects when testing, simulating a legacy root.
51
51
  */
52
52
  const act = React__namespace.act;
53
53
  const isOrthographicCamera = def => def && def.isOrthographicCamera;
54
54
  const isRef = obj => obj && obj.hasOwnProperty('current');
55
55
 
56
- /**
57
- * An SSR-friendly useLayoutEffect.
58
- *
59
- * React currently throws a warning when using useLayoutEffect on the server.
60
- * To get around it, we can conditionally useEffect on the server (no-op) and
61
- * useLayoutEffect elsewhere.
62
- *
63
- * @see https://github.com/facebook/react/issues/14927
56
+ /**
57
+ * An SSR-friendly useLayoutEffect.
58
+ *
59
+ * React currently throws a warning when using useLayoutEffect on the server.
60
+ * To get around it, we can conditionally useEffect on the server (no-op) and
61
+ * useLayoutEffect elsewhere.
62
+ *
63
+ * @see https://github.com/facebook/react/issues/14927
64
64
  */
65
65
  const useIsomorphicLayoutEffect = /* @__PURE__ */((_window$document, _window$navigator) => typeof window !== 'undefined' && (((_window$document = window.document) == null ? void 0 : _window$document.createElement) || ((_window$navigator = window.navigator) == null ? void 0 : _window$navigator.product) === 'ReactNative'))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
66
66
  function useMutableCallback(fn) {
@@ -68,8 +68,8 @@ function useMutableCallback(fn) {
68
68
  useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
69
69
  return ref;
70
70
  }
71
- /**
72
- * Bridges renderer Context and StrictMode from a primary renderer.
71
+ /**
72
+ * Bridges renderer Context and StrictMode from a primary renderer.
73
73
  */
74
74
  function useBridge() {
75
75
  const fiber = itsFine.useFiber();
@@ -121,8 +121,8 @@ function calculateDpr(dpr) {
121
121
  return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
122
122
  }
123
123
 
124
- /**
125
- * Returns instance root state
124
+ /**
125
+ * Returns instance root state
126
126
  */
127
127
  function getRootState(obj) {
128
128
  var _r3f;
@@ -230,10 +230,7 @@ function prepare(target, root, type, props) {
230
230
  handlers: {},
231
231
  isHidden: false
232
232
  };
233
- if (object) {
234
- object.__r3f = instance;
235
- if (type) applyProps(object, instance.props);
236
- }
233
+ if (object) object.__r3f = instance;
237
234
  }
238
235
  return instance;
239
236
  }
@@ -383,6 +380,7 @@ function applyProps(object, props) {
383
380
  if (instance && EVENT_REGEX.test(prop)) {
384
381
  if (typeof value === 'function') instance.handlers[prop] = value;else delete instance.handlers[prop];
385
382
  instance.eventCount = Object.keys(instance.handlers).length;
383
+ continue;
386
384
  }
387
385
 
388
386
  // Ignore setting undefined props
@@ -485,9 +483,9 @@ function makeId(event) {
485
483
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
486
484
  }
487
485
 
488
- /**
489
- * Release pointer captures.
490
- * This is called by releasePointerCapture in the API, and when an object is removed.
486
+ /**
487
+ * Release pointer captures.
488
+ * This is called by releasePointerCapture in the API, and when an object is removed.
491
489
  */
492
490
  function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
493
491
  const captureData = captures.get(obj);
@@ -623,7 +621,19 @@ function createEvents(store) {
623
621
  stopped: false
624
622
  };
625
623
  for (const hit of intersections) {
626
- const state = getRootState(hit.object);
624
+ let state = getRootState(hit.object);
625
+
626
+ // If the object is not managed by R3F, it might be parented to an element which is.
627
+ // Traverse upwards until we find a managed parent and use its state instead.
628
+ if (!state) {
629
+ hit.object.traverseAncestors(obj => {
630
+ const parentState = getRootState(obj);
631
+ if (parentState) {
632
+ state = parentState;
633
+ return false;
634
+ }
635
+ });
636
+ }
627
637
  if (state) {
628
638
  const {
629
639
  raycaster,
@@ -822,19 +832,19 @@ function createEvents(store) {
822
832
  if (!(instance != null && instance.eventCount)) return;
823
833
  const handlers = instance.handlers;
824
834
 
825
- /*
826
- MAYBE TODO, DELETE IF NOT:
827
- Check if the object is captured, captured events should not have intersects running in parallel
828
- But wouldn't it be better to just replace capturedMap with a single entry?
829
- Also, are we OK with straight up making picking up multiple objects impossible?
830
-
831
- const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
832
- if (pointerId !== undefined) {
833
- const capturedMeshSet = internal.capturedMap.get(pointerId)
834
- if (capturedMeshSet) {
835
- const captured = capturedMeshSet.get(eventObject)
836
- if (captured && captured.localState.stopped) return
837
- }
835
+ /*
836
+ MAYBE TODO, DELETE IF NOT:
837
+ Check if the object is captured, captured events should not have intersects running in parallel
838
+ But wouldn't it be better to just replace capturedMap with a single entry?
839
+ Also, are we OK with straight up making picking up multiple objects impossible?
840
+
841
+ const pointerId = (data as ThreeEvent<PointerEvent>).pointerId
842
+ if (pointerId !== undefined) {
843
+ const capturedMeshSet = internal.capturedMap.get(pointerId)
844
+ if (capturedMeshSet) {
845
+ const captured = capturedMeshSet.get(eventObject)
846
+ if (captured && captured.localState.stopped) return
847
+ }
838
848
  }*/
839
849
 
840
850
  if (isPointerMove) {
@@ -1125,11 +1135,11 @@ const createStore = (invalidate, advance) => {
1125
1135
  return rootStore;
1126
1136
  };
1127
1137
 
1128
- /**
1129
- * Exposes an object's {@link Instance}.
1130
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1131
- *
1132
- * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1138
+ /**
1139
+ * Exposes an object's {@link Instance}.
1140
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#useInstanceHandle
1141
+ *
1142
+ * **Note**: this is an escape hatch to react-internal fields. Expect this to change significantly between versions.
1133
1143
  */
1134
1144
  function useInstanceHandle(ref) {
1135
1145
  const instance = React__namespace.useRef(null);
@@ -1137,9 +1147,9 @@ function useInstanceHandle(ref) {
1137
1147
  return instance;
1138
1148
  }
1139
1149
 
1140
- /**
1141
- * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
1142
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
1150
+ /**
1151
+ * Returns the R3F Canvas' Zustand store. Useful for [transient updates](https://github.com/pmndrs/zustand#transient-updates-for-often-occurring-state-changes).
1152
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usestore
1143
1153
  */
1144
1154
  function useStore() {
1145
1155
  const store = React__namespace.useContext(context);
@@ -1147,18 +1157,18 @@ function useStore() {
1147
1157
  return store;
1148
1158
  }
1149
1159
 
1150
- /**
1151
- * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1152
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1160
+ /**
1161
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1162
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1153
1163
  */
1154
1164
  function useThree(selector = state => state, equalityFn) {
1155
1165
  return useStore()(selector, equalityFn);
1156
1166
  }
1157
1167
 
1158
- /**
1159
- * Executes a callback before render in a shared frame loop.
1160
- * Can order effects with render priority or manually render with a positive priority.
1161
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1168
+ /**
1169
+ * Executes a callback before render in a shared frame loop.
1170
+ * Can order effects with render priority or manually render with a positive priority.
1171
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1162
1172
  */
1163
1173
  function useFrame(callback, renderPriority = 0) {
1164
1174
  const store = useStore();
@@ -1170,9 +1180,9 @@ function useFrame(callback, renderPriority = 0) {
1170
1180
  return null;
1171
1181
  }
1172
1182
 
1173
- /**
1174
- * Returns a node graph of an object with named nodes & materials.
1175
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1183
+ /**
1184
+ * Returns a node graph of an object with named nodes & materials.
1185
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1176
1186
  */
1177
1187
  function useGraph(object) {
1178
1188
  return React__namespace.useMemo(() => buildGraph(object), [object]);
@@ -1208,11 +1218,11 @@ function loadingFn(extensions, onProgress) {
1208
1218
  };
1209
1219
  }
1210
1220
 
1211
- /**
1212
- * Synchronously loads and caches assets with a three loader.
1213
- *
1214
- * Note: this hook's caller must be wrapped with `React.Suspense`
1215
- * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1221
+ /**
1222
+ * Synchronously loads and caches assets with a three loader.
1223
+ *
1224
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1225
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1216
1226
  */
1217
1227
  function useLoader(loader, input, extensions, onProgress) {
1218
1228
  // Use suspense to load async assets
@@ -1224,16 +1234,16 @@ function useLoader(loader, input, extensions, onProgress) {
1224
1234
  return Array.isArray(input) ? results : results[0];
1225
1235
  }
1226
1236
 
1227
- /**
1228
- * Preloads an asset into cache as a side-effect.
1237
+ /**
1238
+ * Preloads an asset into cache as a side-effect.
1229
1239
  */
1230
1240
  useLoader.preload = function (loader, input, extensions) {
1231
1241
  const keys = Array.isArray(input) ? input : [input];
1232
1242
  return suspendReact.preload(loadingFn(extensions), [loader, ...keys]);
1233
1243
  };
1234
1244
 
1235
- /**
1236
- * Removes a loaded asset from cache.
1245
+ /**
1246
+ * Removes a loaded asset from cache.
1237
1247
  */
1238
1248
  useLoader.clear = function (loader, input) {
1239
1249
  const keys = Array.isArray(input) ? input : [input];
@@ -1259,6 +1269,8 @@ const NoEventPriority = 0;
1259
1269
  // https://github.com/microsoft/TypeScript/issues/37079
1260
1270
 
1261
1271
  const catalogue = {};
1272
+ const PREFIX_REGEX = /^three(?=[A-Z])/;
1273
+ const toPascalCase = type => `${type[0].toUpperCase()}${type.slice(1)}`;
1262
1274
  let i = 0;
1263
1275
  const isConstructor = object => typeof object === 'function';
1264
1276
  function extend(objects) {
@@ -1286,6 +1298,8 @@ function validateInstance(type, props) {
1286
1298
  }
1287
1299
  function createInstance(type, props, root) {
1288
1300
  var _props$object;
1301
+ // Remove three* prefix from elements
1302
+ type = type.replace(PREFIX_REGEX, '');
1289
1303
  validateInstance(type, props);
1290
1304
 
1291
1305
  // Regenerate the R3F instance for primitives to simulate a new object
@@ -1329,17 +1343,16 @@ function handleContainerEffects(parent, child, beforeChild) {
1329
1343
  if (!child.object) {
1330
1344
  var _child$props$object, _child$props$args;
1331
1345
  // Get target from catalogue
1332
- const name = `${child.type[0].toUpperCase()}${child.type.slice(1)}`;
1333
- const target = catalogue[name];
1346
+ const target = catalogue[toPascalCase(child.type)];
1334
1347
 
1335
1348
  // Create object
1336
1349
  child.object = (_child$props$object = child.props.object) != null ? _child$props$object : new target(...((_child$props$args = child.props.args) != null ? _child$props$args : []));
1337
1350
  child.object.__r3f = child;
1338
-
1339
- // Set initial props
1340
- applyProps(child.object, child.props);
1341
1351
  }
1342
1352
 
1353
+ // Set initial props
1354
+ applyProps(child.object, child.props);
1355
+
1343
1356
  // Append instance
1344
1357
  if (child.props.attach) {
1345
1358
  attach(parent, child);
@@ -1351,7 +1364,6 @@ function handleContainerEffects(parent, child, beforeChild) {
1351
1364
  child.object.dispatchEvent({
1352
1365
  type: 'added'
1353
1366
  });
1354
- // expect-error https://github.com/mrdoob/three.js/pull/16934
1355
1367
  parent.object.dispatchEvent({
1356
1368
  type: 'childadded',
1357
1369
  child: child.object
@@ -1497,8 +1509,7 @@ function swapInstances() {
1497
1509
  if (parent) {
1498
1510
  var _instance$props$objec, _instance$props$args;
1499
1511
  // Get target from catalogue
1500
- const name = `${instance.type[0].toUpperCase()}${instance.type.slice(1)}`;
1501
- const target = catalogue[name];
1512
+ const target = catalogue[toPascalCase(instance.type)];
1502
1513
 
1503
1514
  // Create object
1504
1515
  instance.object = (_instance$props$objec = instance.props.object) != null ? _instance$props$objec : new target(...((_instance$props$args = instance.props.args) != null ? _instance$props$args : []));
@@ -1667,20 +1678,6 @@ const shallowLoose = {
1667
1678
  objects: 'shallow',
1668
1679
  strict: false
1669
1680
  };
1670
- async function createRendererInstance(gl, canvas) {
1671
- const defaultProps = {
1672
- canvas: canvas,
1673
- powerPreference: 'high-performance',
1674
- antialias: true,
1675
- alpha: true
1676
- };
1677
- const customRenderer = typeof gl === 'function' ? await gl(defaultProps) : gl;
1678
- if (isRenderer(customRenderer)) return customRenderer;
1679
- return new THREE__namespace.WebGLRenderer({
1680
- ...defaultProps,
1681
- ...gl
1682
- });
1683
- }
1684
1681
  function computeInitialSize(canvas, size) {
1685
1682
  if (!size && typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
1686
1683
  const {
@@ -1758,10 +1755,13 @@ function createRoot(canvas) {
1758
1755
 
1759
1756
  // Locals
1760
1757
  let onCreated;
1761
- let configured = false;
1762
1758
  let lastCamera;
1759
+ let configured = false;
1760
+ let pending = null;
1763
1761
  return {
1764
1762
  async configure(props = {}) {
1763
+ let resolve;
1764
+ pending = new Promise(_resolve => resolve = _resolve);
1765
1765
  let {
1766
1766
  gl: glConfig,
1767
1767
  size: propsSize,
@@ -1784,9 +1784,26 @@ function createRoot(canvas) {
1784
1784
 
1785
1785
  // Set up renderer (one time only!)
1786
1786
  let gl = state.gl;
1787
- if (!state.gl) state.set({
1788
- gl: gl = await createRendererInstance(glConfig, canvas)
1789
- });
1787
+ if (!state.gl) {
1788
+ const defaultProps = {
1789
+ canvas: canvas,
1790
+ powerPreference: 'high-performance',
1791
+ antialias: true,
1792
+ alpha: true
1793
+ };
1794
+ const customRenderer = typeof glConfig === 'function' ? await glConfig(defaultProps) : glConfig;
1795
+ if (isRenderer(customRenderer)) {
1796
+ gl = customRenderer;
1797
+ } else {
1798
+ gl = new THREE__namespace.WebGLRenderer({
1799
+ ...defaultProps,
1800
+ ...glConfig
1801
+ });
1802
+ }
1803
+ state.set({
1804
+ gl
1805
+ });
1806
+ }
1790
1807
 
1791
1808
  // Set up raycaster (one time only!)
1792
1809
  let raycaster = state.raycaster;
@@ -1965,17 +1982,20 @@ function createRoot(canvas) {
1965
1982
  // Set locals
1966
1983
  onCreated = onCreatedCallback;
1967
1984
  configured = true;
1985
+ resolve();
1968
1986
  return this;
1969
1987
  },
1970
1988
  render(children) {
1971
1989
  // The root has to be configured before it can be rendered
1972
- if (!configured) throw "The root has to be configured before it can be rendered, call 'configure' first!";
1973
- reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
1974
- store: store,
1975
- children: children,
1976
- onCreated: onCreated,
1977
- rootElement: canvas
1978
- }), fiber, null, () => undefined);
1990
+ if (!configured && !pending) this.configure();
1991
+ pending.then(() => {
1992
+ reconciler.updateContainer( /*#__PURE__*/jsxRuntime.jsx(Provider, {
1993
+ store: store,
1994
+ children: children,
1995
+ onCreated: onCreated,
1996
+ rootElement: canvas
1997
+ }), fiber, null, () => undefined);
1998
+ });
1979
1999
  return store;
1980
2000
  },
1981
2001
  unmount() {
@@ -2048,10 +2068,10 @@ function Portal({
2048
2068
  children,
2049
2069
  container
2050
2070
  }) {
2051
- /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2052
- * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2053
- * the "R3F hooks can only be used within the Canvas component!" warning:
2054
- * <Canvas>
2071
+ /** This has to be a component because it would not be able to call useThree/useStore otherwise since
2072
+ * if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
2073
+ * the "R3F hooks can only be used within the Canvas component!" warning:
2074
+ * <Canvas>
2055
2075
  * {createPortal(...)} */
2056
2076
  const {
2057
2077
  events,
@@ -2143,21 +2163,21 @@ const globalEffects = new Set();
2143
2163
  const globalAfterEffects = new Set();
2144
2164
  const globalTailEffects = new Set();
2145
2165
 
2146
- /**
2147
- * Adds a global render callback which is called each frame.
2148
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
2166
+ /**
2167
+ * Adds a global render callback which is called each frame.
2168
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
2149
2169
  */
2150
2170
  const addEffect = callback => createSubs(callback, globalEffects);
2151
2171
 
2152
- /**
2153
- * Adds a global after-render callback which is called each frame.
2154
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
2172
+ /**
2173
+ * Adds a global after-render callback which is called each frame.
2174
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
2155
2175
  */
2156
2176
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
2157
2177
 
2158
- /**
2159
- * Adds a global callback which is called when rendering stops.
2160
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
2178
+ /**
2179
+ * Adds a global callback which is called when rendering stops.
2180
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
2161
2181
  */
2162
2182
  const addTail = callback => createSubs(callback, globalTailEffects);
2163
2183
  function run(effects, timestamp) {
@@ -2229,7 +2249,7 @@ function loop(timestamp) {
2229
2249
  repeat += update(timestamp, state);
2230
2250
  }
2231
2251
  }
2232
- useFrameInProgress = true;
2252
+ useFrameInProgress = false;
2233
2253
 
2234
2254
  // Run after-effects
2235
2255
  flushGlobalEffects('after', timestamp);
@@ -2245,9 +2265,9 @@ function loop(timestamp) {
2245
2265
  }
2246
2266
  }
2247
2267
 
2248
- /**
2249
- * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
2250
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
2268
+ /**
2269
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
2270
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
2251
2271
  */
2252
2272
  function invalidate(state, frames = 1) {
2253
2273
  var _state$gl$xr2;
@@ -2274,9 +2294,9 @@ function invalidate(state, frames = 1) {
2274
2294
  }
2275
2295
  }
2276
2296
 
2277
- /**
2278
- * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
2279
- * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
2297
+ /**
2298
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
2299
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
2280
2300
  */
2281
2301
  function advance(timestamp, runGlobalEffects = true, state, frame) {
2282
2302
  if (runGlobalEffects) flushGlobalEffects('before', timestamp);
@@ -2308,7 +2328,7 @@ function createPointerEvents(store) {
2308
2328
  compute(event, state, previous) {
2309
2329
  // https://github.com/pmndrs/react-three-fiber/pull/782
2310
2330
  // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
2311
- state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
2331
+ state.pointer.set((event.offsetX - state.size.left) / state.size.width * 2 - 1, -((event.offsetY - state.size.top) / state.size.height) * 2 + 1);
2312
2332
  state.raycaster.setFromCamera(state.pointer, state.camera);
2313
2333
  },
2314
2334
  connected: undefined,