@react-three/fiber 10.0.0-canary.20de6b2 → 10.0.0-canary.27df622
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 +106 -63
- package/dist/index.d.cts +270 -142
- package/dist/index.d.mts +270 -142
- package/dist/index.d.ts +270 -170
- package/dist/index.mjs +106 -63
- package/dist/legacy.cjs +105 -61
- package/dist/legacy.d.cts +274 -146
- package/dist/legacy.d.mts +274 -146
- package/dist/legacy.d.ts +274 -172
- package/dist/legacy.mjs +105 -61
- package/dist/webgpu/index.cjs +197 -135
- package/dist/webgpu/index.d.cts +333 -204
- package/dist/webgpu/index.d.mts +333 -204
- package/dist/webgpu/index.d.ts +333 -232
- package/dist/webgpu/index.mjs +197 -135
- package/package.json +2 -2
package/dist/legacy.mjs
CHANGED
|
@@ -11,6 +11,7 @@ export { Scheduler, getScheduler } from '@pmndrs/scheduler';
|
|
|
11
11
|
import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
|
|
12
12
|
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
13
13
|
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
14
|
+
import { HDRCubeTextureLoader } from 'three/examples/jsm/loaders/HDRCubeTextureLoader.js';
|
|
14
15
|
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
15
16
|
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
16
17
|
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
@@ -33,11 +34,11 @@ const R3F_BUILD_WEBGPU = false;
|
|
|
33
34
|
async function loadInspector() {
|
|
34
35
|
throw new Error("Inspector is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
+
class WebGPURenderer {
|
|
37
38
|
constructor() {
|
|
38
39
|
throw new Error("WebGPURenderer is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
39
40
|
}
|
|
40
|
-
}
|
|
41
|
+
}
|
|
41
42
|
const RenderTarget = null;
|
|
42
43
|
const CubeRenderTarget = null;
|
|
43
44
|
|
|
@@ -513,8 +514,10 @@ function hasVisibilityHandlers(handlers) {
|
|
|
513
514
|
}
|
|
514
515
|
|
|
515
516
|
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
516
|
-
function fromRef(ref) {
|
|
517
|
-
|
|
517
|
+
function fromRef(ref, transform) {
|
|
518
|
+
const marker = { [FROM_REF]: ref };
|
|
519
|
+
if (transform) marker.transform = transform;
|
|
520
|
+
return marker;
|
|
518
521
|
}
|
|
519
522
|
function isFromRef(value) {
|
|
520
523
|
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
@@ -615,11 +618,9 @@ function diffProps(instance, newProps) {
|
|
|
615
618
|
for (const prop in instance.props) {
|
|
616
619
|
if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
|
|
617
620
|
const { root, key } = resolve(instance.object, prop);
|
|
618
|
-
if (
|
|
621
|
+
if (typeof root?.constructor === "function") {
|
|
619
622
|
const ctor = getMemoizedPrototype(root);
|
|
620
623
|
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
621
|
-
} else {
|
|
622
|
-
changedProps[prop] = 0;
|
|
623
624
|
}
|
|
624
625
|
}
|
|
625
626
|
return changedProps;
|
|
@@ -909,7 +910,7 @@ const createStore = (invalidate, advance) => {
|
|
|
909
910
|
size: newSize,
|
|
910
911
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
911
912
|
}));
|
|
912
|
-
|
|
913
|
+
get().invalidate();
|
|
913
914
|
}
|
|
914
915
|
}
|
|
915
916
|
return;
|
|
@@ -924,15 +925,16 @@ const createStore = (invalidate, advance) => {
|
|
|
924
925
|
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
925
926
|
_sizeImperative: true
|
|
926
927
|
}));
|
|
927
|
-
|
|
928
|
+
get().invalidate();
|
|
928
929
|
},
|
|
929
930
|
setDpr: (dpr) => set((state2) => {
|
|
930
931
|
const resolved = calculateDpr(dpr);
|
|
931
932
|
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
932
933
|
}),
|
|
933
934
|
setFrameloop: (frameloop = "always") => {
|
|
935
|
+
const rootId = get().internal.rootId;
|
|
936
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
934
937
|
set(() => ({ frameloop }));
|
|
935
|
-
getScheduler().frameloop = frameloop;
|
|
936
938
|
},
|
|
937
939
|
setError: (error) => set(() => ({ error })),
|
|
938
940
|
error: null,
|
|
@@ -1051,7 +1053,8 @@ const createStore = (invalidate, advance) => {
|
|
|
1051
1053
|
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
1052
1054
|
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
1053
1055
|
resizeTarget.setSize(size.width, size.height, false);
|
|
1054
|
-
|
|
1056
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
1057
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
1055
1058
|
}
|
|
1056
1059
|
if (camera !== oldCamera) {
|
|
1057
1060
|
oldCamera = camera;
|
|
@@ -1237,6 +1240,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1237
1240
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1238
1241
|
*/
|
|
1239
1242
|
scheduler: scheduler2,
|
|
1243
|
+
/**
|
|
1244
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1245
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1246
|
+
*/
|
|
1247
|
+
get rootId() {
|
|
1248
|
+
return getScheduler().getJobRootId(id);
|
|
1249
|
+
},
|
|
1240
1250
|
/**
|
|
1241
1251
|
* Manually step this job only.
|
|
1242
1252
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1253,6 +1263,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1253
1263
|
stepAll: (timestamp) => {
|
|
1254
1264
|
getScheduler().step(timestamp);
|
|
1255
1265
|
},
|
|
1266
|
+
/**
|
|
1267
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1268
|
+
*/
|
|
1269
|
+
invalidate: (frames, stackFrames) => {
|
|
1270
|
+
const scheduler3 = getScheduler();
|
|
1271
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1272
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1273
|
+
},
|
|
1256
1274
|
/**
|
|
1257
1275
|
* Pause this job (set enabled=false).
|
|
1258
1276
|
* Job remains registered but won't run.
|
|
@@ -1325,12 +1343,24 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1325
1343
|
TextureLoader,
|
|
1326
1344
|
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1327
1345
|
);
|
|
1346
|
+
const mappedTextures = useMemo(() => {
|
|
1347
|
+
if (cachedResult) return cachedResult;
|
|
1348
|
+
if (IsObject(stableInput)) {
|
|
1349
|
+
const keyed = {};
|
|
1350
|
+
const textureArray = loadedTextures;
|
|
1351
|
+
let i = 0;
|
|
1352
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1353
|
+
return keyed;
|
|
1354
|
+
} else {
|
|
1355
|
+
return loadedTextures;
|
|
1356
|
+
}
|
|
1357
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1328
1358
|
useLayoutEffect(() => {
|
|
1329
1359
|
if (cachedResult) return;
|
|
1330
1360
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
1331
1361
|
onLoadCalledForRef.current = inputKey;
|
|
1332
|
-
onLoadRef.current?.(
|
|
1333
|
-
}, [cachedResult,
|
|
1362
|
+
onLoadRef.current?.(mappedTextures);
|
|
1363
|
+
}, [cachedResult, mappedTextures, inputKey]);
|
|
1334
1364
|
useEffect(() => {
|
|
1335
1365
|
if (cachedResult) return;
|
|
1336
1366
|
if ("initTexture" in renderer) {
|
|
@@ -1349,18 +1379,6 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1349
1379
|
});
|
|
1350
1380
|
}
|
|
1351
1381
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1352
|
-
const mappedTextures = useMemo(() => {
|
|
1353
|
-
if (cachedResult) return cachedResult;
|
|
1354
|
-
if (IsObject(stableInput)) {
|
|
1355
|
-
const keyed = {};
|
|
1356
|
-
const textureArray = loadedTextures;
|
|
1357
|
-
let i = 0;
|
|
1358
|
-
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1359
|
-
return keyed;
|
|
1360
|
-
} else {
|
|
1361
|
-
return loadedTextures;
|
|
1362
|
-
}
|
|
1363
|
-
}, [stableInput, loadedTextures, cachedResult]);
|
|
1364
1382
|
useEffect(() => {
|
|
1365
1383
|
if (!cache) return;
|
|
1366
1384
|
const urlTextureMap = [];
|
|
@@ -1562,7 +1580,7 @@ function useEnvironment({
|
|
|
1562
1580
|
texture = texture.renderTarget?.texture;
|
|
1563
1581
|
}
|
|
1564
1582
|
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
1565
|
-
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
1583
|
+
texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
|
|
1566
1584
|
return texture;
|
|
1567
1585
|
}
|
|
1568
1586
|
const preloadDefaultOptions = {
|
|
@@ -1615,11 +1633,12 @@ function getExtension(files) {
|
|
|
1615
1633
|
const isCubemap = isArray(files) && files.length === 6;
|
|
1616
1634
|
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1617
1635
|
const firstEntry = isArray(files) ? files[0] : files;
|
|
1618
|
-
const
|
|
1636
|
+
const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1637
|
+
const extension = isCubemap ? firstExtension === "hdr" ? "hdr-cube" : "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstExtension;
|
|
1619
1638
|
return { extension, isCubemap, isGainmap };
|
|
1620
1639
|
}
|
|
1621
1640
|
function getLoader(extension) {
|
|
1622
|
-
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1641
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1623
1642
|
return loader;
|
|
1624
1643
|
}
|
|
1625
1644
|
|
|
@@ -1670,13 +1689,19 @@ function addTail(callback) {
|
|
|
1670
1689
|
return getScheduler().onIdle(callback);
|
|
1671
1690
|
}
|
|
1672
1691
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1673
|
-
|
|
1692
|
+
const rootId = state?.internal?.rootId;
|
|
1693
|
+
const scheduler = getScheduler();
|
|
1694
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1695
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1674
1696
|
}
|
|
1675
|
-
function advance(timestamp) {
|
|
1676
|
-
|
|
1697
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1698
|
+
const rootId = state?.internal?.rootId;
|
|
1699
|
+
const scheduler = getScheduler();
|
|
1700
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1701
|
+
else scheduler.step(timestamp);
|
|
1677
1702
|
}
|
|
1678
1703
|
|
|
1679
|
-
const version = "10.0.0-alpha.
|
|
1704
|
+
const version = "10.0.0-alpha.5";
|
|
1680
1705
|
const packageData = {
|
|
1681
1706
|
version: version};
|
|
1682
1707
|
|
|
@@ -13535,7 +13560,10 @@ function extend(objects) {
|
|
|
13535
13560
|
catalogue[Component] = objects;
|
|
13536
13561
|
return Component;
|
|
13537
13562
|
} else {
|
|
13538
|
-
|
|
13563
|
+
for (const name in objects) {
|
|
13564
|
+
const object = objects[name];
|
|
13565
|
+
if (isConstructor(object)) catalogue[name] = object;
|
|
13566
|
+
}
|
|
13539
13567
|
}
|
|
13540
13568
|
}
|
|
13541
13569
|
function validateInstance(type, props) {
|
|
@@ -13883,7 +13911,7 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13883
13911
|
getRootHostContext: () => NO_CONTEXT,
|
|
13884
13912
|
getChildHostContext: () => NO_CONTEXT,
|
|
13885
13913
|
commitUpdate(instance, type, oldProps, newProps, fiber) {
|
|
13886
|
-
validateInstance(type, newProps);
|
|
13914
|
+
validateInstance(instance.type, newProps);
|
|
13887
13915
|
let reconstruct = false;
|
|
13888
13916
|
if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
|
|
13889
13917
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
@@ -13910,8 +13938,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13910
13938
|
for (const prop in instance.props) {
|
|
13911
13939
|
const value = instance.props[prop];
|
|
13912
13940
|
if (isFromRef(value)) {
|
|
13913
|
-
const ref = value
|
|
13914
|
-
if (ref.current != null) resolved[prop] = ref.current;
|
|
13941
|
+
const { [FROM_REF]: ref, transform } = value;
|
|
13942
|
+
if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
|
|
13915
13943
|
}
|
|
13916
13944
|
}
|
|
13917
13945
|
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
@@ -14288,7 +14316,7 @@ function createRoot(canvas) {
|
|
|
14288
14316
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14289
14317
|
const state2 = store.getState();
|
|
14290
14318
|
if (state2.frameloop === "never") return;
|
|
14291
|
-
advance(timestamp);
|
|
14319
|
+
advance(timestamp, true, state2);
|
|
14292
14320
|
};
|
|
14293
14321
|
const actualRenderer = state.internal.actualRenderer;
|
|
14294
14322
|
const handleSessionChange = () => {
|
|
@@ -14296,7 +14324,7 @@ function createRoot(canvas) {
|
|
|
14296
14324
|
const renderer2 = state2.internal.actualRenderer;
|
|
14297
14325
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14298
14326
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14299
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14327
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14300
14328
|
};
|
|
14301
14329
|
const xr = {
|
|
14302
14330
|
connect() {
|
|
@@ -14378,14 +14406,19 @@ function createRoot(canvas) {
|
|
|
14378
14406
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14379
14407
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14380
14408
|
getState: () => store.getState(),
|
|
14381
|
-
onError: (err) => store.getState().setError(err)
|
|
14409
|
+
onError: (err) => store.getState().setError(err),
|
|
14410
|
+
frameloop: store.getState().frameloop,
|
|
14411
|
+
before: schedulerConfig?.before,
|
|
14412
|
+
after: schedulerConfig?.after,
|
|
14413
|
+
order: schedulerConfig?.order
|
|
14382
14414
|
});
|
|
14383
14415
|
const unregisterCanvasTarget = scheduler.register(
|
|
14384
14416
|
() => {
|
|
14385
14417
|
const state2 = store.getState();
|
|
14386
|
-
|
|
14418
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14419
|
+
if (canvasTarget) {
|
|
14387
14420
|
const renderer2 = state2.internal.actualRenderer;
|
|
14388
|
-
renderer2.setCanvasTarget(
|
|
14421
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14389
14422
|
if (state2.internal.canvasTargetSizeDirty) {
|
|
14390
14423
|
state2.internal.canvasTargetSizeDirty = false;
|
|
14391
14424
|
renderer2.backend?.updateSize?.();
|
|
@@ -14458,8 +14491,7 @@ function createRoot(canvas) {
|
|
|
14458
14491
|
phase: "render",
|
|
14459
14492
|
system: true,
|
|
14460
14493
|
// Internal flag: this is a system job, not user-controlled
|
|
14461
|
-
//
|
|
14462
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14494
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14463
14495
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14464
14496
|
}
|
|
14465
14497
|
);
|
|
@@ -14478,8 +14510,21 @@ function createRoot(canvas) {
|
|
|
14478
14510
|
scheduler
|
|
14479
14511
|
}
|
|
14480
14512
|
}));
|
|
14513
|
+
} else {
|
|
14514
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14515
|
+
if (constraintsChanged) {
|
|
14516
|
+
scheduler.setRootConstraints(rootId, {
|
|
14517
|
+
before: schedulerConfig?.before,
|
|
14518
|
+
after: schedulerConfig?.after
|
|
14519
|
+
});
|
|
14520
|
+
}
|
|
14521
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14522
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14523
|
+
}
|
|
14481
14524
|
}
|
|
14482
|
-
|
|
14525
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14526
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14527
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14483
14528
|
onCreated = onCreatedCallback;
|
|
14484
14529
|
configured = true;
|
|
14485
14530
|
resolve();
|
|
@@ -14521,18 +14566,23 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14521
14566
|
const fiber = root?.fiber;
|
|
14522
14567
|
if (fiber) {
|
|
14523
14568
|
const state = root?.store.getState();
|
|
14524
|
-
if (state)
|
|
14569
|
+
if (state) {
|
|
14570
|
+
state.internal.active = false;
|
|
14571
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14572
|
+
if (unregisterRoot) {
|
|
14573
|
+
unregisterRoot();
|
|
14574
|
+
state.internal.unregisterRoot = void 0;
|
|
14575
|
+
}
|
|
14576
|
+
}
|
|
14525
14577
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14526
14578
|
if (state) {
|
|
14527
14579
|
setTimeout(() => {
|
|
14528
14580
|
try {
|
|
14529
14581
|
const renderer = state.internal.actualRenderer;
|
|
14530
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14531
|
-
if (unregisterRoot) unregisterRoot();
|
|
14532
14582
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14533
14583
|
if (unregisterPrimary) unregisterPrimary();
|
|
14534
14584
|
const canvasTarget = state.internal.canvasTarget;
|
|
14535
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14585
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14536
14586
|
state.events.disconnect?.();
|
|
14537
14587
|
cleanupHelperGroup(root.store);
|
|
14538
14588
|
if (state.isLegacy && renderer) {
|
|
@@ -14673,16 +14723,11 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14673
14723
|
const oldbg = target.background;
|
|
14674
14724
|
const oldenv = target.environment;
|
|
14675
14725
|
const oldSceneProps = {
|
|
14676
|
-
// @ts-ignore
|
|
14677
14726
|
backgroundBlurriness: target.backgroundBlurriness,
|
|
14678
|
-
// @ts-ignore
|
|
14679
14727
|
backgroundIntensity: target.backgroundIntensity,
|
|
14680
|
-
|
|
14681
|
-
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
14682
|
-
// @ts-ignore
|
|
14728
|
+
backgroundRotation: target.backgroundRotation.clone(),
|
|
14683
14729
|
environmentIntensity: target.environmentIntensity,
|
|
14684
|
-
|
|
14685
|
-
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
14730
|
+
environmentRotation: target.environmentRotation.clone()
|
|
14686
14731
|
};
|
|
14687
14732
|
if (background !== "only") target.environment = texture;
|
|
14688
14733
|
if (background) target.background = texture;
|
|
@@ -14976,9 +15021,9 @@ function CanvasImpl({
|
|
|
14976
15021
|
React.useMemo(() => extend(THREE), []);
|
|
14977
15022
|
const Bridge = useBridge();
|
|
14978
15023
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
14979
|
-
const
|
|
15024
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
14980
15025
|
const measureConfig = React.useMemo(() => {
|
|
14981
|
-
if (!
|
|
15026
|
+
if (!hasInitialSize) {
|
|
14982
15027
|
return {
|
|
14983
15028
|
...resize,
|
|
14984
15029
|
scroll: resize?.scroll ?? true,
|
|
@@ -14990,7 +15035,7 @@ function CanvasImpl({
|
|
|
14990
15035
|
debounce: { scroll: 50, resize: 0 },
|
|
14991
15036
|
...resize
|
|
14992
15037
|
};
|
|
14993
|
-
}, [
|
|
15038
|
+
}, [hasInitialSize, resize]);
|
|
14994
15039
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
14995
15040
|
const effectiveSize = React.useMemo(() => {
|
|
14996
15041
|
let w = width ?? containerRect.width;
|
|
@@ -15006,9 +15051,7 @@ function CanvasImpl({
|
|
|
15006
15051
|
left: containerRect.left
|
|
15007
15052
|
};
|
|
15008
15053
|
}, [width, height, containerRect, forceEven]);
|
|
15009
|
-
if (!
|
|
15010
|
-
hasInitialSizeRef.current = true;
|
|
15011
|
-
}
|
|
15054
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15012
15055
|
const canvasRef = React.useRef(null);
|
|
15013
15056
|
const divRef = React.useRef(null);
|
|
15014
15057
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15122,6 +15165,7 @@ function CanvasImpl({
|
|
|
15122
15165
|
const canvas = canvasRef.current;
|
|
15123
15166
|
if (canvas) {
|
|
15124
15167
|
return () => {
|
|
15168
|
+
if (canvas.isConnected) return;
|
|
15125
15169
|
unmountComponentAtNode(canvas);
|
|
15126
15170
|
root.current = null;
|
|
15127
15171
|
};
|