@react-three/fiber 10.0.0-canary.ac30da2 → 10.0.0-canary.af75fd4

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/dist/index.mjs CHANGED
@@ -905,7 +905,7 @@ const createStore = (invalidate, advance) => {
905
905
  size: newSize,
906
906
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
907
907
  }));
908
- getScheduler().invalidate();
908
+ get().invalidate();
909
909
  }
910
910
  }
911
911
  return;
@@ -920,15 +920,16 @@ const createStore = (invalidate, advance) => {
920
920
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
921
921
  _sizeImperative: true
922
922
  }));
923
- getScheduler().invalidate();
923
+ get().invalidate();
924
924
  },
925
925
  setDpr: (dpr) => set((state2) => {
926
926
  const resolved = calculateDpr(dpr);
927
927
  return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
928
928
  }),
929
929
  setFrameloop: (frameloop = "always") => {
930
+ const rootId = get().internal.rootId;
931
+ if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
930
932
  set(() => ({ frameloop }));
931
- getScheduler().frameloop = frameloop;
932
933
  },
933
934
  setError: (error) => set(() => ({ error })),
934
935
  error: null,
@@ -1047,7 +1048,8 @@ const createStore = (invalidate, advance) => {
1047
1048
  const resizeTarget = canvasTarget ?? actualRenderer;
1048
1049
  if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
1049
1050
  resizeTarget.setSize(size.width, size.height, false);
1050
- internal.canvasTargetSizeDirty = true;
1051
+ const activeTarget = actualRenderer.getCanvasTarget?.();
1052
+ if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
1051
1053
  }
1052
1054
  if (camera !== oldCamera) {
1053
1055
  oldCamera = camera;
@@ -1233,6 +1235,13 @@ function useFrame(callback, priorityOrOptions) {
1233
1235
  * Use for controlling the entire frame loop, adding phases, etc.
1234
1236
  */
1235
1237
  scheduler: scheduler2,
1238
+ /**
1239
+ * The root that currently owns this job. Resolve on access because ambient
1240
+ * jobs can be adopted by a Canvas after the controls object is created.
1241
+ */
1242
+ get rootId() {
1243
+ return getScheduler().getJobRootId(id);
1244
+ },
1236
1245
  /**
1237
1246
  * Manually step this job only.
1238
1247
  * Bypasses FPS limiting - always runs.
@@ -1249,6 +1258,14 @@ function useFrame(callback, priorityOrOptions) {
1249
1258
  stepAll: (timestamp) => {
1250
1259
  getScheduler().step(timestamp);
1251
1260
  },
1261
+ /**
1262
+ * Request frames for this job's owning root without waking sibling roots.
1263
+ */
1264
+ invalidate: (frames, stackFrames) => {
1265
+ const scheduler3 = getScheduler();
1266
+ const rootId = scheduler3.getJobRootId(id);
1267
+ if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
1268
+ },
1252
1269
  /**
1253
1270
  * Pause this job (set enabled=false).
1254
1271
  * Job remains registered but won't run.
@@ -1668,13 +1685,19 @@ function addTail(callback) {
1668
1685
  return getScheduler().onIdle(callback);
1669
1686
  }
1670
1687
  function invalidate(state, frames = 1, stackFrames = false) {
1671
- getScheduler().invalidate(frames, stackFrames);
1688
+ const rootId = state?.internal?.rootId;
1689
+ const scheduler = getScheduler();
1690
+ if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
1691
+ else scheduler.invalidate(frames, stackFrames);
1672
1692
  }
1673
- function advance(timestamp) {
1674
- getScheduler().step(timestamp);
1693
+ function advance(timestamp, runGlobalEffects, state) {
1694
+ const rootId = state?.internal?.rootId;
1695
+ const scheduler = getScheduler();
1696
+ if (rootId) scheduler.stepRoot(rootId, timestamp);
1697
+ else scheduler.step(timestamp);
1675
1698
  }
1676
1699
 
1677
- const version = "10.0.0-alpha.3";
1700
+ const version = "10.0.0-alpha.4";
1678
1701
  const packageData = {
1679
1702
  version: version};
1680
1703
 
@@ -14208,9 +14231,8 @@ function createRoot(canvas) {
14208
14231
  if (!renderer.hasInitialized?.()) {
14209
14232
  const size2 = computeInitialSize(canvas, propsSize);
14210
14233
  if (size2.width > 0 && size2.height > 0) {
14211
- const pixelRatio = calculateDpr(dpr);
14212
- canvas.width = size2.width * pixelRatio;
14213
- canvas.height = size2.height * pixelRatio;
14234
+ renderer.setPixelRatio(calculateDpr(dpr));
14235
+ renderer.setSize(size2.width, size2.height, false);
14214
14236
  }
14215
14237
  await renderer.init();
14216
14238
  }
@@ -14219,7 +14241,7 @@ function createRoot(canvas) {
14219
14241
  state.internal.actualRenderer = renderer;
14220
14242
  state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
14221
14243
  if (canvasId && !state.internal.isSecondary) {
14222
- const canvasTarget = new CanvasTarget(canvas);
14244
+ const canvasTarget = renderer.getCanvasTarget?.();
14223
14245
  const unregisterPrimary = registerPrimary(canvasId, renderer, store);
14224
14246
  state.set((prev) => ({
14225
14247
  internal: {
@@ -14333,7 +14355,7 @@ function createRoot(canvas) {
14333
14355
  const handleXRFrame = (timestamp, _frame) => {
14334
14356
  const state2 = store.getState();
14335
14357
  if (state2.frameloop === "never") return;
14336
- advance(timestamp);
14358
+ advance(timestamp, true, state2);
14337
14359
  };
14338
14360
  const actualRenderer = state.internal.actualRenderer;
14339
14361
  const handleSessionChange = () => {
@@ -14341,7 +14363,7 @@ function createRoot(canvas) {
14341
14363
  const renderer2 = state2.internal.actualRenderer;
14342
14364
  actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
14343
14365
  renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
14344
- if (!renderer2.xr.isPresenting) invalidate();
14366
+ if (!renderer2.xr.isPresenting) invalidate(state2);
14345
14367
  };
14346
14368
  const xr = {
14347
14369
  connect() {
@@ -14423,14 +14445,19 @@ function createRoot(canvas) {
14423
14445
  const newRootId = canvasId || scheduler.generateRootId();
14424
14446
  const unregisterRoot = scheduler.registerRoot(newRootId, {
14425
14447
  getState: () => store.getState(),
14426
- onError: (err) => store.getState().setError(err)
14448
+ onError: (err) => store.getState().setError(err),
14449
+ frameloop: store.getState().frameloop,
14450
+ before: schedulerConfig?.before,
14451
+ after: schedulerConfig?.after,
14452
+ order: schedulerConfig?.order
14427
14453
  });
14428
14454
  const unregisterCanvasTarget = scheduler.register(
14429
14455
  () => {
14430
14456
  const state2 = store.getState();
14431
- if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
14457
+ const canvasTarget = state2.internal.canvasTarget;
14458
+ if (canvasTarget) {
14432
14459
  const renderer2 = state2.internal.actualRenderer;
14433
- renderer2.setCanvasTarget(state2.internal.canvasTarget);
14460
+ if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
14434
14461
  if (state2.internal.canvasTargetSizeDirty) {
14435
14462
  state2.internal.canvasTargetSizeDirty = false;
14436
14463
  renderer2.backend?.updateSize?.();
@@ -14503,8 +14530,7 @@ function createRoot(canvas) {
14503
14530
  phase: "render",
14504
14531
  system: true,
14505
14532
  // Internal flag: this is a system job, not user-controlled
14506
- // Apply scheduler config for render ordering and rate limiting
14507
- ...schedulerConfig?.after && { after: schedulerConfig.after },
14533
+ // FPS throttles only the default render job; Canvas ordering belongs to the root.
14508
14534
  ...schedulerConfig?.fps && { fps: schedulerConfig.fps }
14509
14535
  }
14510
14536
  );
@@ -14523,8 +14549,21 @@ function createRoot(canvas) {
14523
14549
  scheduler
14524
14550
  }
14525
14551
  }));
14552
+ } else {
14553
+ const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
14554
+ if (constraintsChanged) {
14555
+ scheduler.setRootConstraints(rootId, {
14556
+ before: schedulerConfig?.before,
14557
+ after: schedulerConfig?.after
14558
+ });
14559
+ }
14560
+ if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
14561
+ scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
14562
+ }
14526
14563
  }
14527
- scheduler.frameloop = frameloop;
14564
+ lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
14565
+ lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
14566
+ lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
14528
14567
  onCreated = onCreatedCallback;
14529
14568
  configured = true;
14530
14569
  resolve();
@@ -14566,18 +14605,23 @@ function unmountComponentAtNode(canvas, callback) {
14566
14605
  const fiber = root?.fiber;
14567
14606
  if (fiber) {
14568
14607
  const state = root?.store.getState();
14569
- if (state) state.internal.active = false;
14608
+ if (state) {
14609
+ state.internal.active = false;
14610
+ const unregisterRoot = state.internal.unregisterRoot;
14611
+ if (unregisterRoot) {
14612
+ unregisterRoot();
14613
+ state.internal.unregisterRoot = void 0;
14614
+ }
14615
+ }
14570
14616
  reconciler.updateContainer(null, fiber, null, () => {
14571
14617
  if (state) {
14572
14618
  setTimeout(() => {
14573
14619
  try {
14574
14620
  const renderer = state.internal.actualRenderer;
14575
- const unregisterRoot = state.internal.unregisterRoot;
14576
- if (unregisterRoot) unregisterRoot();
14577
14621
  const unregisterPrimary = state.internal.unregisterPrimary;
14578
14622
  if (unregisterPrimary) unregisterPrimary();
14579
14623
  const canvasTarget = state.internal.canvasTarget;
14580
- if (canvasTarget?.dispose) canvasTarget.dispose();
14624
+ if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
14581
14625
  state.events.disconnect?.();
14582
14626
  cleanupHelperGroup(root.store);
14583
14627
  if (state.isLegacy && renderer) {
@@ -15021,9 +15065,9 @@ function CanvasImpl({
15021
15065
  React.useMemo(() => extend(THREE), []);
15022
15066
  const Bridge = useBridge();
15023
15067
  const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
15024
- const hasInitialSizeRef = React.useRef(false);
15068
+ const [hasInitialSize, setHasInitialSize] = React.useState(false);
15025
15069
  const measureConfig = React.useMemo(() => {
15026
- if (!hasInitialSizeRef.current) {
15070
+ if (!hasInitialSize) {
15027
15071
  return {
15028
15072
  ...resize,
15029
15073
  scroll: resize?.scroll ?? true,
@@ -15035,7 +15079,7 @@ function CanvasImpl({
15035
15079
  debounce: { scroll: 50, resize: 0 },
15036
15080
  ...resize
15037
15081
  };
15038
- }, [resize, hasInitialSizeRef.current]);
15082
+ }, [hasInitialSize, resize]);
15039
15083
  const [containerRef, containerRect] = useMeasure(measureConfig);
15040
15084
  const effectiveSize = React.useMemo(() => {
15041
15085
  let w = width ?? containerRect.width;
@@ -15051,9 +15095,7 @@ function CanvasImpl({
15051
15095
  left: containerRect.left
15052
15096
  };
15053
15097
  }, [width, height, containerRect, forceEven]);
15054
- if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
15055
- hasInitialSizeRef.current = true;
15056
- }
15098
+ if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
15057
15099
  const canvasRef = React.useRef(null);
15058
15100
  const divRef = React.useRef(null);
15059
15101
  React.useImperativeHandle(ref, () => canvasRef.current);
package/dist/legacy.cjs CHANGED
@@ -929,7 +929,7 @@ const createStore = (invalidate, advance) => {
929
929
  size: newSize,
930
930
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
931
931
  }));
932
- scheduler.getScheduler().invalidate();
932
+ get().invalidate();
933
933
  }
934
934
  }
935
935
  return;
@@ -944,15 +944,16 @@ const createStore = (invalidate, advance) => {
944
944
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
945
945
  _sizeImperative: true
946
946
  }));
947
- scheduler.getScheduler().invalidate();
947
+ get().invalidate();
948
948
  },
949
949
  setDpr: (dpr) => set((state2) => {
950
950
  const resolved = calculateDpr(dpr);
951
951
  return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
952
952
  }),
953
953
  setFrameloop: (frameloop = "always") => {
954
+ const rootId = get().internal.rootId;
955
+ if (rootId) scheduler.getScheduler().setRootFrameloop(rootId, frameloop);
954
956
  set(() => ({ frameloop }));
955
- scheduler.getScheduler().frameloop = frameloop;
956
957
  },
957
958
  setError: (error) => set(() => ({ error })),
958
959
  error: null,
@@ -1071,7 +1072,8 @@ const createStore = (invalidate, advance) => {
1071
1072
  const resizeTarget = canvasTarget ?? actualRenderer;
1072
1073
  if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
1073
1074
  resizeTarget.setSize(size.width, size.height, false);
1074
- internal.canvasTargetSizeDirty = true;
1075
+ const activeTarget = actualRenderer.getCanvasTarget?.();
1076
+ if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
1075
1077
  }
1076
1078
  if (camera !== oldCamera) {
1077
1079
  oldCamera = camera;
@@ -1257,6 +1259,13 @@ function useFrame(callback, priorityOrOptions) {
1257
1259
  * Use for controlling the entire frame loop, adding phases, etc.
1258
1260
  */
1259
1261
  scheduler: scheduler2,
1262
+ /**
1263
+ * The root that currently owns this job. Resolve on access because ambient
1264
+ * jobs can be adopted by a Canvas after the controls object is created.
1265
+ */
1266
+ get rootId() {
1267
+ return scheduler.getScheduler().getJobRootId(id);
1268
+ },
1260
1269
  /**
1261
1270
  * Manually step this job only.
1262
1271
  * Bypasses FPS limiting - always runs.
@@ -1273,6 +1282,14 @@ function useFrame(callback, priorityOrOptions) {
1273
1282
  stepAll: (timestamp) => {
1274
1283
  scheduler.getScheduler().step(timestamp);
1275
1284
  },
1285
+ /**
1286
+ * Request frames for this job's owning root without waking sibling roots.
1287
+ */
1288
+ invalidate: (frames, stackFrames) => {
1289
+ const scheduler3 = scheduler.getScheduler();
1290
+ const rootId = scheduler3.getJobRootId(id);
1291
+ if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
1292
+ },
1276
1293
  /**
1277
1294
  * Pause this job (set enabled=false).
1278
1295
  * Job remains registered but won't run.
@@ -1690,13 +1707,19 @@ function addTail(callback) {
1690
1707
  return scheduler.getScheduler().onIdle(callback);
1691
1708
  }
1692
1709
  function invalidate(state, frames = 1, stackFrames = false) {
1693
- scheduler.getScheduler().invalidate(frames, stackFrames);
1710
+ const rootId = state?.internal?.rootId;
1711
+ const scheduler$1 = scheduler.getScheduler();
1712
+ if (rootId) scheduler$1.invalidateRoot(rootId, frames, stackFrames);
1713
+ else scheduler$1.invalidate(frames, stackFrames);
1694
1714
  }
1695
- function advance(timestamp) {
1696
- scheduler.getScheduler().step(timestamp);
1715
+ function advance(timestamp, runGlobalEffects, state) {
1716
+ const rootId = state?.internal?.rootId;
1717
+ const scheduler$1 = scheduler.getScheduler();
1718
+ if (rootId) scheduler$1.stepRoot(rootId, timestamp);
1719
+ else scheduler$1.step(timestamp);
1697
1720
  }
1698
1721
 
1699
- const version = "10.0.0-alpha.3";
1722
+ const version = "10.0.0-alpha.4";
1700
1723
  const packageData = {
1701
1724
  version: version};
1702
1725
 
@@ -14308,7 +14331,7 @@ function createRoot(canvas) {
14308
14331
  const handleXRFrame = (timestamp, _frame) => {
14309
14332
  const state2 = store.getState();
14310
14333
  if (state2.frameloop === "never") return;
14311
- advance(timestamp);
14334
+ advance(timestamp, true, state2);
14312
14335
  };
14313
14336
  const actualRenderer = state.internal.actualRenderer;
14314
14337
  const handleSessionChange = () => {
@@ -14316,7 +14339,7 @@ function createRoot(canvas) {
14316
14339
  const renderer2 = state2.internal.actualRenderer;
14317
14340
  actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
14318
14341
  renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
14319
- if (!renderer2.xr.isPresenting) invalidate();
14342
+ if (!renderer2.xr.isPresenting) invalidate(state2);
14320
14343
  };
14321
14344
  const xr = {
14322
14345
  connect() {
@@ -14398,14 +14421,19 @@ function createRoot(canvas) {
14398
14421
  const newRootId = canvasId || scheduler$1.generateRootId();
14399
14422
  const unregisterRoot = scheduler$1.registerRoot(newRootId, {
14400
14423
  getState: () => store.getState(),
14401
- onError: (err) => store.getState().setError(err)
14424
+ onError: (err) => store.getState().setError(err),
14425
+ frameloop: store.getState().frameloop,
14426
+ before: schedulerConfig?.before,
14427
+ after: schedulerConfig?.after,
14428
+ order: schedulerConfig?.order
14402
14429
  });
14403
14430
  const unregisterCanvasTarget = scheduler$1.register(
14404
14431
  () => {
14405
14432
  const state2 = store.getState();
14406
- if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
14433
+ const canvasTarget = state2.internal.canvasTarget;
14434
+ if (canvasTarget) {
14407
14435
  const renderer2 = state2.internal.actualRenderer;
14408
- renderer2.setCanvasTarget(state2.internal.canvasTarget);
14436
+ if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
14409
14437
  if (state2.internal.canvasTargetSizeDirty) {
14410
14438
  state2.internal.canvasTargetSizeDirty = false;
14411
14439
  renderer2.backend?.updateSize?.();
@@ -14478,8 +14506,7 @@ function createRoot(canvas) {
14478
14506
  phase: "render",
14479
14507
  system: true,
14480
14508
  // Internal flag: this is a system job, not user-controlled
14481
- // Apply scheduler config for render ordering and rate limiting
14482
- ...schedulerConfig?.after && { after: schedulerConfig.after },
14509
+ // FPS throttles only the default render job; Canvas ordering belongs to the root.
14483
14510
  ...schedulerConfig?.fps && { fps: schedulerConfig.fps }
14484
14511
  }
14485
14512
  );
@@ -14498,8 +14525,21 @@ function createRoot(canvas) {
14498
14525
  scheduler: scheduler$1
14499
14526
  }
14500
14527
  }));
14528
+ } else {
14529
+ const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
14530
+ if (constraintsChanged) {
14531
+ scheduler$1.setRootConstraints(rootId, {
14532
+ before: schedulerConfig?.before,
14533
+ after: schedulerConfig?.after
14534
+ });
14535
+ }
14536
+ if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
14537
+ scheduler$1.setRootOrder(rootId, schedulerConfig?.order ?? 0);
14538
+ }
14501
14539
  }
14502
- scheduler$1.frameloop = frameloop;
14540
+ lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
14541
+ lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
14542
+ lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
14503
14543
  onCreated = onCreatedCallback;
14504
14544
  configured = true;
14505
14545
  resolve();
@@ -14541,18 +14581,23 @@ function unmountComponentAtNode(canvas, callback) {
14541
14581
  const fiber = root?.fiber;
14542
14582
  if (fiber) {
14543
14583
  const state = root?.store.getState();
14544
- if (state) state.internal.active = false;
14584
+ if (state) {
14585
+ state.internal.active = false;
14586
+ const unregisterRoot = state.internal.unregisterRoot;
14587
+ if (unregisterRoot) {
14588
+ unregisterRoot();
14589
+ state.internal.unregisterRoot = void 0;
14590
+ }
14591
+ }
14545
14592
  reconciler.updateContainer(null, fiber, null, () => {
14546
14593
  if (state) {
14547
14594
  setTimeout(() => {
14548
14595
  try {
14549
14596
  const renderer = state.internal.actualRenderer;
14550
- const unregisterRoot = state.internal.unregisterRoot;
14551
- if (unregisterRoot) unregisterRoot();
14552
14597
  const unregisterPrimary = state.internal.unregisterPrimary;
14553
14598
  if (unregisterPrimary) unregisterPrimary();
14554
14599
  const canvasTarget = state.internal.canvasTarget;
14555
- if (canvasTarget?.dispose) canvasTarget.dispose();
14600
+ if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
14556
14601
  state.events.disconnect?.();
14557
14602
  cleanupHelperGroup(root.store);
14558
14603
  if (state.isLegacy && renderer) {
@@ -14996,9 +15041,9 @@ function CanvasImpl({
14996
15041
  React__namespace.useMemo(() => extend(THREE), []);
14997
15042
  const Bridge = useBridge();
14998
15043
  const backgroundProps = React__namespace.useMemo(() => parseBackground(background), [background]);
14999
- const hasInitialSizeRef = React__namespace.useRef(false);
15044
+ const [hasInitialSize, setHasInitialSize] = React__namespace.useState(false);
15000
15045
  const measureConfig = React__namespace.useMemo(() => {
15001
- if (!hasInitialSizeRef.current) {
15046
+ if (!hasInitialSize) {
15002
15047
  return {
15003
15048
  ...resize,
15004
15049
  scroll: resize?.scroll ?? true,
@@ -15010,7 +15055,7 @@ function CanvasImpl({
15010
15055
  debounce: { scroll: 50, resize: 0 },
15011
15056
  ...resize
15012
15057
  };
15013
- }, [resize, hasInitialSizeRef.current]);
15058
+ }, [hasInitialSize, resize]);
15014
15059
  const [containerRef, containerRect] = useMeasure__default(measureConfig);
15015
15060
  const effectiveSize = React__namespace.useMemo(() => {
15016
15061
  let w = width ?? containerRect.width;
@@ -15026,9 +15071,7 @@ function CanvasImpl({
15026
15071
  left: containerRect.left
15027
15072
  };
15028
15073
  }, [width, height, containerRect, forceEven]);
15029
- if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
15030
- hasInitialSizeRef.current = true;
15031
- }
15074
+ if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
15032
15075
  const canvasRef = React__namespace.useRef(null);
15033
15076
  const divRef = React__namespace.useRef(null);
15034
15077
  React__namespace.useImperativeHandle(ref, () => canvasRef.current);