@react-three/fiber 10.0.0-canary.8f5b4d3 → 10.0.0-canary.979dc2d
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.cjs +120 -62
- package/dist/index.d.cts +180 -26
- package/dist/index.d.mts +180 -26
- package/dist/index.d.ts +180 -26
- package/dist/index.mjs +120 -62
- package/dist/legacy.cjs +116 -62
- package/dist/legacy.d.cts +179 -29
- package/dist/legacy.d.mts +179 -29
- package/dist/legacy.d.ts +179 -29
- package/dist/legacy.mjs +116 -62
- package/dist/webgpu/index.cjs +183 -99
- package/dist/webgpu/index.d.cts +204 -90
- package/dist/webgpu/index.d.mts +204 -90
- package/dist/webgpu/index.d.ts +204 -90
- package/dist/webgpu/index.mjs +183 -99
- package/package.json +4 -4
- package/readme.md +1 -1
- package/react-reconciler/constants.d.ts +0 -7
- package/react-reconciler/constants.js +0 -1
- package/react-reconciler/index.d.ts +0 -1044
- package/react-reconciler/index.js +0 -208
package/dist/legacy.mjs
CHANGED
|
@@ -30,11 +30,9 @@ function _mergeNamespaces(n, m) {
|
|
|
30
30
|
|
|
31
31
|
const R3F_BUILD_LEGACY = true;
|
|
32
32
|
const R3F_BUILD_WEBGPU = false;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
};
|
|
33
|
+
async function loadInspector() {
|
|
34
|
+
throw new Error("Inspector is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
35
|
+
}
|
|
38
36
|
const WebGPURenderer = class WebGPURenderer2 {
|
|
39
37
|
constructor() {
|
|
40
38
|
throw new Error("WebGPURenderer is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
@@ -47,12 +45,12 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
47
45
|
__proto__: null,
|
|
48
46
|
CubeRenderTarget: CubeRenderTarget,
|
|
49
47
|
CubeRenderTargetCompat: WebGLCubeRenderTarget,
|
|
50
|
-
Inspector: Inspector,
|
|
51
48
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
52
49
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
53
50
|
RenderTarget: RenderTarget,
|
|
54
51
|
RenderTargetCompat: WebGLRenderTarget,
|
|
55
|
-
WebGPURenderer: WebGPURenderer
|
|
52
|
+
WebGPURenderer: WebGPURenderer,
|
|
53
|
+
loadInspector: loadInspector
|
|
56
54
|
}, [three]);
|
|
57
55
|
|
|
58
56
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -911,7 +909,7 @@ const createStore = (invalidate, advance) => {
|
|
|
911
909
|
size: newSize,
|
|
912
910
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
913
911
|
}));
|
|
914
|
-
|
|
912
|
+
get().invalidate();
|
|
915
913
|
}
|
|
916
914
|
}
|
|
917
915
|
return;
|
|
@@ -926,15 +924,16 @@ const createStore = (invalidate, advance) => {
|
|
|
926
924
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
927
925
|
_sizeImperative: true
|
|
928
926
|
}));
|
|
929
|
-
|
|
927
|
+
get().invalidate();
|
|
930
928
|
},
|
|
931
929
|
setDpr: (dpr) => set((state2) => {
|
|
932
930
|
const resolved = calculateDpr(dpr);
|
|
933
931
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
934
932
|
}),
|
|
935
933
|
setFrameloop: (frameloop = "always") => {
|
|
934
|
+
const rootId = get().internal.rootId;
|
|
935
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
936
936
|
set(() => ({ frameloop }));
|
|
937
|
-
getScheduler().frameloop = frameloop;
|
|
938
937
|
},
|
|
939
938
|
setError: (error) => set(() => ({ error })),
|
|
940
939
|
error: null,
|
|
@@ -1050,17 +1049,11 @@ const createStore = (invalidate, advance) => {
|
|
|
1050
1049
|
oldSize = size;
|
|
1051
1050
|
oldDpr = viewport.dpr;
|
|
1052
1051
|
updateCamera(camera, size);
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1059
|
-
if (canvasTarget) {
|
|
1060
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1061
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1052
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1053
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1054
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
1055
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
1056
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
1064
1057
|
}
|
|
1065
1058
|
if (camera !== oldCamera) {
|
|
1066
1059
|
oldCamera = camera;
|
|
@@ -1122,7 +1115,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1122
1115
|
const results = cacheKeys.map(
|
|
1123
1116
|
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1124
1117
|
);
|
|
1125
|
-
|
|
1118
|
+
const stableRef = useRef(null);
|
|
1119
|
+
const previous = stableRef.current;
|
|
1120
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
1121
|
+
stableRef.current = stable;
|
|
1122
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1126
1123
|
}
|
|
1127
1124
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1128
1125
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1242,6 +1239,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1242
1239
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1243
1240
|
*/
|
|
1244
1241
|
scheduler: scheduler2,
|
|
1242
|
+
/**
|
|
1243
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1244
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1245
|
+
*/
|
|
1246
|
+
get rootId() {
|
|
1247
|
+
return getScheduler().getJobRootId(id);
|
|
1248
|
+
},
|
|
1245
1249
|
/**
|
|
1246
1250
|
* Manually step this job only.
|
|
1247
1251
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1258,6 +1262,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1258
1262
|
stepAll: (timestamp) => {
|
|
1259
1263
|
getScheduler().step(timestamp);
|
|
1260
1264
|
},
|
|
1265
|
+
/**
|
|
1266
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1267
|
+
*/
|
|
1268
|
+
invalidate: (frames, stackFrames) => {
|
|
1269
|
+
const scheduler3 = getScheduler();
|
|
1270
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1271
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1272
|
+
},
|
|
1261
1273
|
/**
|
|
1262
1274
|
* Pause this job (set enabled=false).
|
|
1263
1275
|
* Job remains registered but won't run.
|
|
@@ -1287,6 +1299,11 @@ function getUrls(input) {
|
|
|
1287
1299
|
if (Array.isArray(input)) return input;
|
|
1288
1300
|
return Object.values(input);
|
|
1289
1301
|
}
|
|
1302
|
+
function inputSignature(input) {
|
|
1303
|
+
if (typeof input === "string") return input;
|
|
1304
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1305
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1306
|
+
}
|
|
1290
1307
|
function allUrlsCached(urls, textureCache) {
|
|
1291
1308
|
return urls.every((url) => textureCache.has(url));
|
|
1292
1309
|
}
|
|
@@ -1312,18 +1329,19 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1312
1329
|
const onLoadRef = useRef(onLoad);
|
|
1313
1330
|
onLoadRef.current = onLoad;
|
|
1314
1331
|
const onLoadCalledForRef = useRef(null);
|
|
1315
|
-
const
|
|
1332
|
+
const inputKey = useMemo(() => inputSignature(input), [input]);
|
|
1333
|
+
const stableInput = useMemo(() => input, [inputKey]);
|
|
1334
|
+
const urls = useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1316
1335
|
const cachedResult = useMemo(() => {
|
|
1317
1336
|
if (!cache) return null;
|
|
1318
1337
|
const textures = store.getState().textures;
|
|
1319
1338
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1320
|
-
return buildFromCache(
|
|
1321
|
-
}, [cache, urls,
|
|
1339
|
+
return buildFromCache(stableInput, textures);
|
|
1340
|
+
}, [cache, urls, stableInput, store]);
|
|
1322
1341
|
const loadedTextures = useLoader(
|
|
1323
1342
|
TextureLoader,
|
|
1324
|
-
IsObject(
|
|
1343
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1325
1344
|
);
|
|
1326
|
-
const inputKey = urls.join("\0");
|
|
1327
1345
|
useLayoutEffect(() => {
|
|
1328
1346
|
if (cachedResult) return;
|
|
1329
1347
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
@@ -1350,28 +1368,28 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1350
1368
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1351
1369
|
const mappedTextures = useMemo(() => {
|
|
1352
1370
|
if (cachedResult) return cachedResult;
|
|
1353
|
-
if (IsObject(
|
|
1371
|
+
if (IsObject(stableInput)) {
|
|
1354
1372
|
const keyed = {};
|
|
1355
1373
|
const textureArray = loadedTextures;
|
|
1356
1374
|
let i = 0;
|
|
1357
|
-
for (const key in
|
|
1375
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1358
1376
|
return keyed;
|
|
1359
1377
|
} else {
|
|
1360
1378
|
return loadedTextures;
|
|
1361
1379
|
}
|
|
1362
|
-
}, [
|
|
1380
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1363
1381
|
useEffect(() => {
|
|
1364
1382
|
if (!cache) return;
|
|
1365
1383
|
const urlTextureMap = [];
|
|
1366
|
-
if (typeof
|
|
1367
|
-
urlTextureMap.push([
|
|
1368
|
-
} else if (Array.isArray(
|
|
1384
|
+
if (typeof stableInput === "string") {
|
|
1385
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1386
|
+
} else if (Array.isArray(stableInput)) {
|
|
1369
1387
|
const textureArray = mappedTextures;
|
|
1370
|
-
|
|
1371
|
-
} else if (IsObject(
|
|
1388
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1389
|
+
} else if (IsObject(stableInput)) {
|
|
1372
1390
|
const textureRecord = mappedTextures;
|
|
1373
|
-
for (const key in
|
|
1374
|
-
const url =
|
|
1391
|
+
for (const key in stableInput) {
|
|
1392
|
+
const url = stableInput[key];
|
|
1375
1393
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1376
1394
|
}
|
|
1377
1395
|
}
|
|
@@ -1400,7 +1418,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1400
1418
|
}
|
|
1401
1419
|
return { _textureRefs: refs };
|
|
1402
1420
|
});
|
|
1403
|
-
}, [cache,
|
|
1421
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1404
1422
|
return mappedTextures;
|
|
1405
1423
|
}
|
|
1406
1424
|
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
@@ -1669,13 +1687,19 @@ function addTail(callback) {
|
|
|
1669
1687
|
return getScheduler().onIdle(callback);
|
|
1670
1688
|
}
|
|
1671
1689
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1672
|
-
|
|
1690
|
+
const rootId = state?.internal?.rootId;
|
|
1691
|
+
const scheduler = getScheduler();
|
|
1692
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1693
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1673
1694
|
}
|
|
1674
|
-
function advance(timestamp) {
|
|
1675
|
-
|
|
1695
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1696
|
+
const rootId = state?.internal?.rootId;
|
|
1697
|
+
const scheduler = getScheduler();
|
|
1698
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1699
|
+
else scheduler.step(timestamp);
|
|
1676
1700
|
}
|
|
1677
1701
|
|
|
1678
|
-
const version = "10.0.0-alpha.
|
|
1702
|
+
const version = "10.0.0-alpha.4";
|
|
1679
1703
|
const packageData = {
|
|
1680
1704
|
version: version};
|
|
1681
1705
|
|
|
@@ -12958,7 +12982,10 @@ function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
|
12958
12982
|
const captureData = pointerState.captured.get(obj);
|
|
12959
12983
|
if (captureData) {
|
|
12960
12984
|
pointerState.captured.delete(obj);
|
|
12961
|
-
|
|
12985
|
+
try {
|
|
12986
|
+
captureData.target.releasePointerCapture?.(pointerId);
|
|
12987
|
+
} catch {
|
|
12988
|
+
}
|
|
12962
12989
|
}
|
|
12963
12990
|
}
|
|
12964
12991
|
function swapInteractivity(store, object, newObject) {
|
|
@@ -13052,7 +13079,9 @@ function createEvents(store) {
|
|
|
13052
13079
|
state2.events.compute?.(event, state2, state2.previousRoot?.getState());
|
|
13053
13080
|
if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
|
|
13054
13081
|
}
|
|
13055
|
-
|
|
13082
|
+
if (!state2.raycaster.camera) return [];
|
|
13083
|
+
obj.updateWorldMatrix(true, true);
|
|
13084
|
+
return state2.raycaster.intersectObject(obj, true);
|
|
13056
13085
|
}
|
|
13057
13086
|
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
13058
13087
|
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
@@ -14282,7 +14311,7 @@ function createRoot(canvas) {
|
|
|
14282
14311
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14283
14312
|
const state2 = store.getState();
|
|
14284
14313
|
if (state2.frameloop === "never") return;
|
|
14285
|
-
advance(timestamp);
|
|
14314
|
+
advance(timestamp, true, state2);
|
|
14286
14315
|
};
|
|
14287
14316
|
const actualRenderer = state.internal.actualRenderer;
|
|
14288
14317
|
const handleSessionChange = () => {
|
|
@@ -14290,7 +14319,7 @@ function createRoot(canvas) {
|
|
|
14290
14319
|
const renderer2 = state2.internal.actualRenderer;
|
|
14291
14320
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14292
14321
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14293
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14322
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14294
14323
|
};
|
|
14295
14324
|
const xr = {
|
|
14296
14325
|
connect() {
|
|
@@ -14372,14 +14401,23 @@ function createRoot(canvas) {
|
|
|
14372
14401
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14373
14402
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14374
14403
|
getState: () => store.getState(),
|
|
14375
|
-
onError: (err) => store.getState().setError(err)
|
|
14404
|
+
onError: (err) => store.getState().setError(err),
|
|
14405
|
+
frameloop: store.getState().frameloop,
|
|
14406
|
+
before: schedulerConfig?.before,
|
|
14407
|
+
after: schedulerConfig?.after,
|
|
14408
|
+
order: schedulerConfig?.order
|
|
14376
14409
|
});
|
|
14377
14410
|
const unregisterCanvasTarget = scheduler.register(
|
|
14378
14411
|
() => {
|
|
14379
14412
|
const state2 = store.getState();
|
|
14380
|
-
|
|
14413
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14414
|
+
if (canvasTarget) {
|
|
14381
14415
|
const renderer2 = state2.internal.actualRenderer;
|
|
14382
|
-
renderer2.setCanvasTarget(
|
|
14416
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14417
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14418
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14419
|
+
renderer2.backend?.updateSize?.();
|
|
14420
|
+
}
|
|
14383
14421
|
}
|
|
14384
14422
|
},
|
|
14385
14423
|
{
|
|
@@ -14448,8 +14486,7 @@ function createRoot(canvas) {
|
|
|
14448
14486
|
phase: "render",
|
|
14449
14487
|
system: true,
|
|
14450
14488
|
// Internal flag: this is a system job, not user-controlled
|
|
14451
|
-
//
|
|
14452
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14489
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14453
14490
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14454
14491
|
}
|
|
14455
14492
|
);
|
|
@@ -14468,8 +14505,21 @@ function createRoot(canvas) {
|
|
|
14468
14505
|
scheduler
|
|
14469
14506
|
}
|
|
14470
14507
|
}));
|
|
14508
|
+
} else {
|
|
14509
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14510
|
+
if (constraintsChanged) {
|
|
14511
|
+
scheduler.setRootConstraints(rootId, {
|
|
14512
|
+
before: schedulerConfig?.before,
|
|
14513
|
+
after: schedulerConfig?.after
|
|
14514
|
+
});
|
|
14515
|
+
}
|
|
14516
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14517
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14518
|
+
}
|
|
14471
14519
|
}
|
|
14472
|
-
|
|
14520
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14521
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14522
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14473
14523
|
onCreated = onCreatedCallback;
|
|
14474
14524
|
configured = true;
|
|
14475
14525
|
resolve();
|
|
@@ -14511,18 +14561,23 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14511
14561
|
const fiber = root?.fiber;
|
|
14512
14562
|
if (fiber) {
|
|
14513
14563
|
const state = root?.store.getState();
|
|
14514
|
-
if (state)
|
|
14564
|
+
if (state) {
|
|
14565
|
+
state.internal.active = false;
|
|
14566
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14567
|
+
if (unregisterRoot) {
|
|
14568
|
+
unregisterRoot();
|
|
14569
|
+
state.internal.unregisterRoot = void 0;
|
|
14570
|
+
}
|
|
14571
|
+
}
|
|
14515
14572
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14516
14573
|
if (state) {
|
|
14517
14574
|
setTimeout(() => {
|
|
14518
14575
|
try {
|
|
14519
14576
|
const renderer = state.internal.actualRenderer;
|
|
14520
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14521
|
-
if (unregisterRoot) unregisterRoot();
|
|
14522
14577
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14523
14578
|
if (unregisterPrimary) unregisterPrimary();
|
|
14524
14579
|
const canvasTarget = state.internal.canvasTarget;
|
|
14525
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14580
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14526
14581
|
state.events.disconnect?.();
|
|
14527
14582
|
cleanupHelperGroup(root.store);
|
|
14528
14583
|
if (state.isLegacy && renderer) {
|
|
@@ -14966,9 +15021,9 @@ function CanvasImpl({
|
|
|
14966
15021
|
React.useMemo(() => extend(THREE), []);
|
|
14967
15022
|
const Bridge = useBridge();
|
|
14968
15023
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
14969
|
-
const
|
|
15024
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
14970
15025
|
const measureConfig = React.useMemo(() => {
|
|
14971
|
-
if (!
|
|
15026
|
+
if (!hasInitialSize) {
|
|
14972
15027
|
return {
|
|
14973
15028
|
...resize,
|
|
14974
15029
|
scroll: resize?.scroll ?? true,
|
|
@@ -14980,7 +15035,7 @@ function CanvasImpl({
|
|
|
14980
15035
|
debounce: { scroll: 50, resize: 0 },
|
|
14981
15036
|
...resize
|
|
14982
15037
|
};
|
|
14983
|
-
}, [
|
|
15038
|
+
}, [hasInitialSize, resize]);
|
|
14984
15039
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
14985
15040
|
const effectiveSize = React.useMemo(() => {
|
|
14986
15041
|
let w = width ?? containerRect.width;
|
|
@@ -14996,9 +15051,7 @@ function CanvasImpl({
|
|
|
14996
15051
|
left: containerRect.left
|
|
14997
15052
|
};
|
|
14998
15053
|
}, [width, height, containerRect, forceEven]);
|
|
14999
|
-
if (!
|
|
15000
|
-
hasInitialSizeRef.current = true;
|
|
15001
|
-
}
|
|
15054
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15002
15055
|
const canvasRef = React.useRef(null);
|
|
15003
15056
|
const divRef = React.useRef(null);
|
|
15004
15057
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15112,6 +15165,7 @@ function CanvasImpl({
|
|
|
15112
15165
|
const canvas = canvasRef.current;
|
|
15113
15166
|
if (canvas) {
|
|
15114
15167
|
return () => {
|
|
15168
|
+
if (canvas.isConnected) return;
|
|
15115
15169
|
unmountComponentAtNode(canvas);
|
|
15116
15170
|
root.current = null;
|
|
15117
15171
|
};
|