@react-three/fiber 10.0.0-canary.b86abaa → 10.0.0-canary.b9d5979
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/extension.d.cts +3 -3
- package/dist/extension.d.mts +3 -3
- package/dist/extension.d.ts +3 -3
- package/dist/extension.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +3 -3
- package/dist/legacy.cjs +1 -1
- package/dist/legacy.d.cts +4 -4
- package/dist/legacy.d.mts +4 -4
- package/dist/legacy.d.ts +4 -4
- package/dist/legacy.mjs +4 -4
- package/dist/shared/{fiber.tsM9NKZ9.mjs → fiber.5Q8N6Hhq.mjs} +226 -57
- package/dist/shared/{fiber.Cx-UAmMb.d.ts → fiber.B_GGVI86.d.ts} +1 -1
- package/dist/shared/{fiber.DXw-SLsH.d.ts → fiber.BcNm6NAg.d.cts} +88 -4
- package/dist/shared/{fiber.oKEFddXj.cjs → fiber.BegWBc5_.cjs} +226 -57
- package/dist/shared/{fiber.BY6Yf1h-.d.cts → fiber.CQDCACCJ.d.mts} +88 -4
- package/dist/shared/{fiber.B0oukOFO.mjs → fiber.CUKAa7Rv.mjs} +1 -1
- package/dist/shared/{fiber.I5Q4dVvl.d.cts → fiber.CZLeHcML.d.cts} +24 -2
- package/dist/shared/{fiber.I5Q4dVvl.d.mts → fiber.CZLeHcML.d.mts} +24 -2
- package/dist/shared/{fiber.I5Q4dVvl.d.ts → fiber.CZLeHcML.d.ts} +24 -2
- package/dist/shared/{fiber.BU0vBHc9.d.mts → fiber.ColkapKS.d.mts} +1 -1
- package/dist/shared/{fiber.DAl4H27x.d.cts → fiber.DRfTw2kk.d.cts} +1 -1
- package/dist/shared/{fiber.Cu2hX1IM.d.mts → fiber.DeBIf2pk.d.ts} +88 -4
- package/dist/webgpu/index.cjs +1 -1
- package/dist/webgpu/index.d.cts +4 -4
- package/dist/webgpu/index.d.mts +4 -4
- package/dist/webgpu/index.d.ts +4 -4
- package/dist/webgpu/index.mjs +4 -4
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { n as notifyDepreciated, a as useThree, u as useStore, h as unstageTextures, i as stageTextures, j as
|
|
2
|
+
import { n as notifyDepreciated, a as useThree, u as useStore, h as unstageTextures, i as stageTextures, j as attachRootExtensions, k as detachRootExtensions, d as useIsomorphicLayoutEffect, e as useMutableCallback, c as context, b as useFrame, f as useBridge, l as notifyAlpha, E as ErrorBoundary, B as Block, m as notifyRootExtensionsHmr } from './fiber.CUKAa7Rv.mjs';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import React__default, { useRef, useMemo, useLayoutEffect, useEffect, useImperativeHandle, useCallback, useState } from 'react';
|
|
5
5
|
import useMeasure from 'react-use-measure';
|
|
@@ -396,6 +396,15 @@ function isOnce(value) {
|
|
|
396
396
|
return value !== null && typeof value === "object" && ONCE in value;
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
+
function assertNodeMaterialSupported(state, value) {
|
|
400
|
+
if (!state?.isLegacy) return;
|
|
401
|
+
const material = (Array.isArray(value) ? value : [value]).find((m) => m?.isNodeMaterial);
|
|
402
|
+
if (!material) return;
|
|
403
|
+
throw new Error(
|
|
404
|
+
`R3F: ${material.type ?? "Node material"} requires WebGPURenderer (it falls back to WebGL2 automatically). Pass \`renderer\` to <Canvas> from @react-three/fiber, or import from @react-three/fiber/webgpu.`
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
|
|
399
408
|
const RESERVED_PROPS = [
|
|
400
409
|
"children",
|
|
401
410
|
"key",
|
|
@@ -566,6 +575,7 @@ function applyProps(object, props) {
|
|
|
566
575
|
}
|
|
567
576
|
}
|
|
568
577
|
} else {
|
|
578
|
+
if (key === "material") assertNodeMaterialSupported(rootState, value);
|
|
569
579
|
root[key] = value;
|
|
570
580
|
if (key.endsWith("Node") && root.isMaterial) {
|
|
571
581
|
root.needsUpdate = true;
|
|
@@ -13879,11 +13889,16 @@ function validateInstance(type, props, root) {
|
|
|
13879
13889
|
const name = toPascalCase(type);
|
|
13880
13890
|
const target = resolveConstructor(name, root);
|
|
13881
13891
|
if (type !== "primitive" && !target) {
|
|
13892
|
+
if (name.endsWith("NodeMaterial")) {
|
|
13893
|
+
assertNodeMaterialSupported(root.getState(), { isNodeMaterial: true, type: name });
|
|
13894
|
+
}
|
|
13882
13895
|
throw new Error(
|
|
13883
13896
|
`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`
|
|
13884
13897
|
);
|
|
13885
13898
|
}
|
|
13886
13899
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
13900
|
+
assertNodeMaterialSupported(root.getState(), props.object);
|
|
13901
|
+
assertNodeMaterialSupported(root.getState(), props.material);
|
|
13887
13902
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
13888
13903
|
}
|
|
13889
13904
|
function createInstance(type, props, root) {
|
|
@@ -13982,6 +13997,7 @@ function disposeOnIdle(object) {
|
|
|
13982
13997
|
}
|
|
13983
13998
|
function removeChild(parent, child, dispose) {
|
|
13984
13999
|
if (!child) return;
|
|
14000
|
+
const wasLinked = !!child.parent;
|
|
13985
14001
|
child.parent = null;
|
|
13986
14002
|
const childIndex = parent.children.indexOf(child);
|
|
13987
14003
|
if (childIndex !== -1) parent.children.splice(childIndex, 1);
|
|
@@ -14001,7 +14017,10 @@ function removeChild(parent, child, dispose) {
|
|
|
14001
14017
|
if (shouldDispose && child.type !== "primitive" && child.object.type !== "Scene") {
|
|
14002
14018
|
disposeOnIdle(child.object);
|
|
14003
14019
|
}
|
|
14004
|
-
if (dispose === void 0)
|
|
14020
|
+
if (dispose === void 0 && wasLinked) {
|
|
14021
|
+
const state = findInitialRoot(child).getState();
|
|
14022
|
+
if (state.internal.active && state.internal.frames === 0) state.invalidate();
|
|
14023
|
+
}
|
|
14005
14024
|
}
|
|
14006
14025
|
function setFiberRef(fiber, publicInstance) {
|
|
14007
14026
|
for (const _fiber of [fiber, fiber.alternate]) {
|
|
@@ -14750,6 +14769,69 @@ function getPrimaryIds() {
|
|
|
14750
14769
|
return Array.from(primaryRegistry.keys());
|
|
14751
14770
|
}
|
|
14752
14771
|
|
|
14772
|
+
const fulfilled = (value) => Object.assign(Promise.resolve(value), { status: "fulfilled", value });
|
|
14773
|
+
const tracked = (promise) => {
|
|
14774
|
+
const result = Promise.resolve(promise);
|
|
14775
|
+
result.status = "pending";
|
|
14776
|
+
result.then(
|
|
14777
|
+
(value) => {
|
|
14778
|
+
Object.assign(result, { status: "fulfilled", value });
|
|
14779
|
+
},
|
|
14780
|
+
(reason) => {
|
|
14781
|
+
Object.assign(result, { status: "rejected", reason });
|
|
14782
|
+
}
|
|
14783
|
+
);
|
|
14784
|
+
return result;
|
|
14785
|
+
};
|
|
14786
|
+
|
|
14787
|
+
const records = /* @__PURE__ */ new WeakMap();
|
|
14788
|
+
function take(renderer, record) {
|
|
14789
|
+
record.leases++;
|
|
14790
|
+
let released = false;
|
|
14791
|
+
return () => {
|
|
14792
|
+
if (released) return;
|
|
14793
|
+
released = true;
|
|
14794
|
+
if (--record.leases > 0) return;
|
|
14795
|
+
records.delete(renderer);
|
|
14796
|
+
if (record.owned) return disposeRenderer(renderer);
|
|
14797
|
+
};
|
|
14798
|
+
}
|
|
14799
|
+
function leaseRenderer(renderer, owned) {
|
|
14800
|
+
let record = records.get(renderer);
|
|
14801
|
+
if (!record) records.set(renderer, record = { owned, leases: 0 });
|
|
14802
|
+
return take(renderer, record);
|
|
14803
|
+
}
|
|
14804
|
+
function borrowRenderer(renderer) {
|
|
14805
|
+
const record = records.get(renderer);
|
|
14806
|
+
if (!record) throw new Error("R3F: cannot share a renderer whose canvas has already unmounted");
|
|
14807
|
+
return take(renderer, record);
|
|
14808
|
+
}
|
|
14809
|
+
function disposeRenderer(renderer) {
|
|
14810
|
+
if (renderer.hasInitialized?.() === false) return;
|
|
14811
|
+
const warn = (error) => console.warn("[R3F] Error disposing renderer", error);
|
|
14812
|
+
const loseContext = () => {
|
|
14813
|
+
try {
|
|
14814
|
+
;
|
|
14815
|
+
renderer.forceContextLoss?.();
|
|
14816
|
+
} catch (error) {
|
|
14817
|
+
warn(error);
|
|
14818
|
+
}
|
|
14819
|
+
};
|
|
14820
|
+
let disposed;
|
|
14821
|
+
try {
|
|
14822
|
+
disposed = renderer.dispose();
|
|
14823
|
+
} catch (error) {
|
|
14824
|
+
warn(error);
|
|
14825
|
+
}
|
|
14826
|
+
if (typeof disposed?.then === "function") {
|
|
14827
|
+
return Promise.resolve(disposed).then(loseContext, (error) => {
|
|
14828
|
+
warn(error);
|
|
14829
|
+
loseContext();
|
|
14830
|
+
});
|
|
14831
|
+
}
|
|
14832
|
+
loseContext();
|
|
14833
|
+
}
|
|
14834
|
+
|
|
14753
14835
|
const isRenderer = (def) => !!def?.render;
|
|
14754
14836
|
const _roots = /* @__PURE__ */ new Map();
|
|
14755
14837
|
function ensureStoreThreeObjects(store) {
|
|
@@ -14761,9 +14843,9 @@ function ensureStoreThreeObjects(store) {
|
|
|
14761
14843
|
}
|
|
14762
14844
|
const shallowLoose = { objects: "shallow", strict: false };
|
|
14763
14845
|
async function resolveRenderer(config, defaultProps, RendererClass) {
|
|
14764
|
-
if (typeof config === "function") return await config(defaultProps);
|
|
14765
|
-
if (isRenderer(config)) return config;
|
|
14766
|
-
return new RendererClass({ ...defaultProps, ...config });
|
|
14846
|
+
if (typeof config === "function") return { renderer: await config(defaultProps), owned: true };
|
|
14847
|
+
if (isRenderer(config)) return { renderer: config, owned: false };
|
|
14848
|
+
return { renderer: new RendererClass({ ...defaultProps, ...config }), owned: true };
|
|
14767
14849
|
}
|
|
14768
14850
|
function computeInitialSize(canvas, size) {
|
|
14769
14851
|
if (!size && typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
|
|
@@ -14779,6 +14861,34 @@ function computeInitialSize(canvas, size) {
|
|
|
14779
14861
|
}
|
|
14780
14862
|
return { width: 0, height: 0, top: 0, left: 0, ...size };
|
|
14781
14863
|
}
|
|
14864
|
+
function watchDpr(onChange) {
|
|
14865
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function" || !window.devicePixelRatio) {
|
|
14866
|
+
return () => {
|
|
14867
|
+
};
|
|
14868
|
+
}
|
|
14869
|
+
let query;
|
|
14870
|
+
const listen = () => {
|
|
14871
|
+
try {
|
|
14872
|
+
query = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
14873
|
+
if (typeof query?.addEventListener === "function") query.addEventListener("change", handleChange);
|
|
14874
|
+
else query?.addListener?.(handleChange);
|
|
14875
|
+
} catch {
|
|
14876
|
+
query = void 0;
|
|
14877
|
+
}
|
|
14878
|
+
};
|
|
14879
|
+
const unlisten = () => {
|
|
14880
|
+
if (typeof query?.removeEventListener === "function") query.removeEventListener("change", handleChange);
|
|
14881
|
+
else query?.removeListener?.(handleChange);
|
|
14882
|
+
query = void 0;
|
|
14883
|
+
};
|
|
14884
|
+
const handleChange = () => {
|
|
14885
|
+
unlisten();
|
|
14886
|
+
listen();
|
|
14887
|
+
onChange();
|
|
14888
|
+
};
|
|
14889
|
+
listen();
|
|
14890
|
+
return unlisten;
|
|
14891
|
+
}
|
|
14782
14892
|
function createRoot(canvas, provider) {
|
|
14783
14893
|
const prevRoot = _roots.get(canvas);
|
|
14784
14894
|
const prevFiber = prevRoot?.fiber;
|
|
@@ -14815,15 +14925,39 @@ function createRoot(canvas, provider) {
|
|
|
14815
14925
|
null
|
|
14816
14926
|
// transitionCallbacks
|
|
14817
14927
|
);
|
|
14818
|
-
|
|
14928
|
+
const root = prevRoot || { fiber, store, unmountClaim: null, ready: fulfilled(void 0) };
|
|
14929
|
+
if (!prevRoot) _roots.set(canvas, root);
|
|
14819
14930
|
let onCreated;
|
|
14820
14931
|
let lastCamera;
|
|
14821
14932
|
const lastConfiguredProps = {};
|
|
14933
|
+
let resolvedDpr = 0;
|
|
14934
|
+
let dprChangedInXR = false;
|
|
14935
|
+
let unwatchDpr;
|
|
14936
|
+
const resolveDpr = () => {
|
|
14937
|
+
if (_roots.get(canvas)?.store !== store) return unwatchDpr?.();
|
|
14938
|
+
const state = store.getState();
|
|
14939
|
+
const xr = state.internal.actualRenderer?.xr;
|
|
14940
|
+
if (xr?.isPresenting || xr?.getSession?.()) {
|
|
14941
|
+
dprChangedInXR = true;
|
|
14942
|
+
return;
|
|
14943
|
+
}
|
|
14944
|
+
dprChangedInXR = false;
|
|
14945
|
+
const dpr = lastConfiguredProps.dpr;
|
|
14946
|
+
if (dpr === void 0 || state.viewport.dpr !== resolvedDpr || calculateDpr(dpr) === resolvedDpr) return;
|
|
14947
|
+
state.setDpr(dpr);
|
|
14948
|
+
resolvedDpr = store.getState().viewport.dpr;
|
|
14949
|
+
};
|
|
14822
14950
|
let configured = false;
|
|
14823
14951
|
let pending = null;
|
|
14824
|
-
|
|
14952
|
+
const cancelUnmount = () => {
|
|
14953
|
+
if (!root.unmountClaim) return;
|
|
14954
|
+
root.unmountClaim = null;
|
|
14955
|
+
store.getState().internal.active = true;
|
|
14956
|
+
};
|
|
14825
14957
|
return {
|
|
14826
14958
|
async configure(props = {}) {
|
|
14959
|
+
if (_roots.get(canvas) !== root) throw new Error("R3F: cannot configure a root after it has unmounted");
|
|
14960
|
+
cancelUnmount();
|
|
14827
14961
|
let resolve;
|
|
14828
14962
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14829
14963
|
const {
|
|
@@ -14897,20 +15031,23 @@ function createRoot(canvas, provider) {
|
|
|
14897
15031
|
);
|
|
14898
15032
|
}
|
|
14899
15033
|
if (!state.internal.actualRenderer) {
|
|
14900
|
-
if (
|
|
14901
|
-
|
|
15034
|
+
if (root.ready.status !== "pending") {
|
|
15035
|
+
const setup = (async () => {
|
|
14902
15036
|
const support = wantsGL ? await webgl() : await webgpu();
|
|
14903
15037
|
registerThree(support.three);
|
|
14904
15038
|
state.internal.support = support;
|
|
14905
15039
|
ensureStoreThreeObjects(store);
|
|
14906
15040
|
if (support.kind === "webgl") {
|
|
14907
|
-
|
|
15041
|
+
const resolved = await resolveRenderer(glConfig, defaultGLProps, support.Renderer);
|
|
15042
|
+
renderer = resolved.renderer;
|
|
14908
15043
|
state.internal.actualRenderer = renderer;
|
|
15044
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
14909
15045
|
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14910
15046
|
} else if (primaryCanvas) {
|
|
14911
15047
|
const primary = await waitForPrimary(primaryCanvas);
|
|
14912
15048
|
renderer = primary.renderer;
|
|
14913
15049
|
state.internal.actualRenderer = renderer;
|
|
15050
|
+
state.internal.releaseRenderer = borrowRenderer(renderer);
|
|
14914
15051
|
const canvasTarget = new support.CanvasTarget(canvas);
|
|
14915
15052
|
primary.store.setState((prev) => ({
|
|
14916
15053
|
internal: { ...prev.internal, isMultiCanvas: true }
|
|
@@ -14928,7 +15065,8 @@ function createRoot(canvas, provider) {
|
|
|
14928
15065
|
}
|
|
14929
15066
|
}));
|
|
14930
15067
|
} else {
|
|
14931
|
-
|
|
15068
|
+
const resolved = await resolveRenderer(rendererConfig, defaultGPUProps, support.Renderer);
|
|
15069
|
+
renderer = resolved.renderer;
|
|
14932
15070
|
if (!renderer.hasInitialized?.()) {
|
|
14933
15071
|
const size2 = computeInitialSize(canvas, propsSize);
|
|
14934
15072
|
if (size2.width > 0 && size2.height > 0) {
|
|
@@ -14940,6 +15078,7 @@ function createRoot(canvas, provider) {
|
|
|
14940
15078
|
const backend = renderer.backend;
|
|
14941
15079
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14942
15080
|
state.internal.actualRenderer = renderer;
|
|
15081
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
14943
15082
|
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
14944
15083
|
if (canvasId && !state.internal.isSecondary) {
|
|
14945
15084
|
const canvasTarget = renderer.getCanvasTarget?.();
|
|
@@ -14953,12 +15092,10 @@ function createRoot(canvas, provider) {
|
|
|
14953
15092
|
}));
|
|
14954
15093
|
}
|
|
14955
15094
|
}
|
|
14956
|
-
})()
|
|
14957
|
-
|
|
14958
|
-
throw err;
|
|
14959
|
-
});
|
|
15095
|
+
})();
|
|
15096
|
+
root.ready = tracked(setup);
|
|
14960
15097
|
}
|
|
14961
|
-
await
|
|
15098
|
+
await root.ready;
|
|
14962
15099
|
state = store.getState();
|
|
14963
15100
|
renderer = state.internal.actualRenderer;
|
|
14964
15101
|
}
|
|
@@ -15037,6 +15174,12 @@ function createRoot(canvas, provider) {
|
|
|
15037
15174
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
15038
15175
|
state.setDpr(dpr);
|
|
15039
15176
|
lastConfiguredProps.dpr = dpr;
|
|
15177
|
+
resolvedDpr = store.getState().viewport.dpr;
|
|
15178
|
+
}
|
|
15179
|
+
const internal = store.getState().internal;
|
|
15180
|
+
if (Array.isArray(dpr) && (!unwatchDpr || internal.unwatchDpr !== unwatchDpr)) {
|
|
15181
|
+
internal.unwatchDpr?.();
|
|
15182
|
+
internal.unwatchDpr = unwatchDpr = watchDpr(resolveDpr);
|
|
15040
15183
|
}
|
|
15041
15184
|
if (frameloop !== void 0 && frameloop !== lastConfiguredProps.frameloop) {
|
|
15042
15185
|
state.setFrameloop(frameloop);
|
|
@@ -15065,7 +15208,10 @@ function createRoot(canvas, provider) {
|
|
|
15065
15208
|
const renderer2 = state2.internal.actualRenderer;
|
|
15066
15209
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
15067
15210
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
15068
|
-
if (!renderer2.xr.isPresenting)
|
|
15211
|
+
if (!renderer2.xr.isPresenting) {
|
|
15212
|
+
if (dprChangedInXR) resolveDpr();
|
|
15213
|
+
invalidate(state2);
|
|
15214
|
+
}
|
|
15069
15215
|
};
|
|
15070
15216
|
const xr = {
|
|
15071
15217
|
connect() {
|
|
@@ -15275,8 +15421,11 @@ function createRoot(canvas, provider) {
|
|
|
15275
15421
|
return this;
|
|
15276
15422
|
},
|
|
15277
15423
|
render(children) {
|
|
15424
|
+
if (_roots.get(canvas) !== root) return store;
|
|
15425
|
+
cancelUnmount();
|
|
15278
15426
|
if (!configured && !pending) this.configure();
|
|
15279
15427
|
pending.then(() => {
|
|
15428
|
+
if (_roots.get(canvas) !== root || root.unmountClaim) return;
|
|
15280
15429
|
reconciler.updateContainer(
|
|
15281
15430
|
/* @__PURE__ */ jsx(Provider, { store, children, onCreated, rootElement: canvas }),
|
|
15282
15431
|
fiber,
|
|
@@ -15287,7 +15436,7 @@ function createRoot(canvas, provider) {
|
|
|
15287
15436
|
return store;
|
|
15288
15437
|
},
|
|
15289
15438
|
unmount() {
|
|
15290
|
-
unmountComponentAtNode(canvas);
|
|
15439
|
+
if (_roots.get(canvas) === root) unmountComponentAtNode(canvas);
|
|
15291
15440
|
}
|
|
15292
15441
|
};
|
|
15293
15442
|
}
|
|
@@ -15307,46 +15456,52 @@ function Provider({
|
|
|
15307
15456
|
}
|
|
15308
15457
|
function unmountComponentAtNode(canvas, callback) {
|
|
15309
15458
|
const root = _roots.get(canvas);
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
|
|
15313
|
-
|
|
15314
|
-
|
|
15315
|
-
|
|
15316
|
-
if (
|
|
15317
|
-
|
|
15318
|
-
|
|
15459
|
+
if (!root) return;
|
|
15460
|
+
const claim = root.unmountClaim = Symbol("unmount");
|
|
15461
|
+
root.store.getState().internal.active = false;
|
|
15462
|
+
reconciler.updateContainer(null, root.fiber, null, () => {
|
|
15463
|
+
if (root.unmountClaim !== claim) return;
|
|
15464
|
+
reconciler.updateContainer(null, root.fiber, null, () => {
|
|
15465
|
+
if (root.unmountClaim !== claim) return;
|
|
15466
|
+
if (root.ready.status === "pending") root.ready.then(teardown, teardown);
|
|
15467
|
+
else teardown();
|
|
15468
|
+
});
|
|
15469
|
+
});
|
|
15470
|
+
function teardown() {
|
|
15471
|
+
if (root.unmountClaim !== claim) return;
|
|
15472
|
+
root.unmountClaim = null;
|
|
15473
|
+
_roots.delete(canvas);
|
|
15474
|
+
const state = root.store.getState();
|
|
15475
|
+
const internal = state.internal;
|
|
15476
|
+
internal.active = false;
|
|
15477
|
+
const attempt = (step) => {
|
|
15478
|
+
try {
|
|
15479
|
+
return step();
|
|
15480
|
+
} catch (error) {
|
|
15481
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
15319
15482
|
}
|
|
15320
|
-
}
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
}
|
|
15341
|
-
dispose(state.scene);
|
|
15342
|
-
_roots.delete(canvas);
|
|
15343
|
-
if (callback) callback(canvas);
|
|
15344
|
-
} catch (error) {
|
|
15345
|
-
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
15346
|
-
}
|
|
15347
|
-
}, 500);
|
|
15483
|
+
};
|
|
15484
|
+
attempt(() => internal.unwatchDpr?.());
|
|
15485
|
+
internal.unwatchDpr = void 0;
|
|
15486
|
+
attempt(() => internal.unregisterRoot?.());
|
|
15487
|
+
internal.unregisterRoot = void 0;
|
|
15488
|
+
attempt(() => detachRootExtensions(root.store));
|
|
15489
|
+
attempt(() => internal.unregisterPrimary?.());
|
|
15490
|
+
attempt(() => state.events.disconnect?.());
|
|
15491
|
+
if (!internal.isSecondary && internal.actualRenderer?.xr && state.xr) attempt(() => state.xr.disconnect());
|
|
15492
|
+
attempt(() => cleanupHelperGroup(root.store));
|
|
15493
|
+
if (state.scene) attempt(() => dispose(state.scene));
|
|
15494
|
+
const canvasTarget = internal.canvasTarget;
|
|
15495
|
+
if (internal.isSecondary && canvasTarget?.dispose) attempt(() => canvasTarget.dispose());
|
|
15496
|
+
const released = attempt(() => internal.releaseRenderer?.());
|
|
15497
|
+
internal.releaseRenderer = void 0;
|
|
15498
|
+
if (callback) {
|
|
15499
|
+
if (released) {
|
|
15500
|
+
released.then(() => callback(canvas)).catch((error) => console.warn("[R3F] Error in unmount callback", error));
|
|
15501
|
+
} else {
|
|
15502
|
+
callback(canvas);
|
|
15348
15503
|
}
|
|
15349
|
-
}
|
|
15504
|
+
}
|
|
15350
15505
|
}
|
|
15351
15506
|
}
|
|
15352
15507
|
function createPortal(children, container, state) {
|
|
@@ -15891,13 +16046,27 @@ function CanvasImpl({
|
|
|
15891
16046
|
}
|
|
15892
16047
|
};
|
|
15893
16048
|
});
|
|
16049
|
+
const insertionMounted = React.useRef(false);
|
|
16050
|
+
React.useInsertionEffect(() => {
|
|
16051
|
+
insertionMounted.current = true;
|
|
16052
|
+
return () => {
|
|
16053
|
+
insertionMounted.current = false;
|
|
16054
|
+
queueMicrotask(() => {
|
|
16055
|
+
if (insertionMounted.current) return;
|
|
16056
|
+
const current = root.current;
|
|
16057
|
+
root.current = null;
|
|
16058
|
+
current?.unmount();
|
|
16059
|
+
});
|
|
16060
|
+
};
|
|
16061
|
+
}, []);
|
|
15894
16062
|
React.useEffect(() => {
|
|
15895
16063
|
const canvas = canvasRef.current;
|
|
15896
16064
|
if (canvas) {
|
|
15897
16065
|
return () => {
|
|
15898
16066
|
if (canvas.isConnected) return;
|
|
15899
|
-
|
|
16067
|
+
const current = root.current;
|
|
15900
16068
|
root.current = null;
|
|
16069
|
+
current?.unmount();
|
|
15901
16070
|
};
|
|
15902
16071
|
}
|
|
15903
16072
|
}, []);
|
|
@@ -3,7 +3,7 @@ import { ReactNode, Component, RefObject, JSX } from 'react';
|
|
|
3
3
|
import { Options } from 'react-use-measure';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { ColorRepresentation, Euler as Euler$1, Loader, RenderTargetOptions as RenderTargetOptions$1, ColorSpace, Texture as Texture$1, CubeTexture, Scene, Object3D } from 'three';
|
|
6
|
-
import {
|
|
6
|
+
import { K as Properties, c as Size, F as Frameloop, e as Performance, D as Dpr, g as RootStore, p as EventManager, f as RootState, n as ComputeFunction, C as ConstructorRepresentation, $ as ObjectMap, I as InternalState, M as Mutable, O as Overwrite, z as Args, l as EventHandlers, G as InstanceProps, k as DomEvent, H as Instance, y as Catalogue, w as Root, a7 as ThreeCore, Y as Bridge, _ as UnblockProps, a1 as Disposable, U as ThreeCamera, a0 as EquConfig } from './fiber.CZLeHcML.cjs';
|
|
7
7
|
import { WebGPURenderer, WebGPURendererParameters } from 'three/webgpu';
|
|
8
8
|
|
|
9
9
|
//* Base Renderer Types =====================================
|
|
@@ -155,8 +155,11 @@ interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas$1> {
|
|
|
155
155
|
/** Dimensions to fit the renderer to. Will measure canvas dimensions if omitted */
|
|
156
156
|
size?: Size
|
|
157
157
|
/**
|
|
158
|
-
* Enables shadows (
|
|
159
|
-
* but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
|
|
158
|
+
* Enables shadows (`true` uses `THREE.PCFShadowMap`). Can accept `renderer.shadowMap` options for
|
|
159
|
+
* fine-tuning, but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
|
|
160
|
+
*
|
|
161
|
+
* `'soft'` is a deprecated alias of `'percentage'`: both map to `THREE.PCFShadowMap`, because three.js
|
|
162
|
+
* deprecated `PCFSoftShadowMap` and made `PCFShadowMap` soft. Using `'soft'` logs a deprecation notice.
|
|
160
163
|
* @see https://threejs.org/docs/#api/en/renderers/WebGLRenderer.shadowMap
|
|
161
164
|
*/
|
|
162
165
|
shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE.WebGLShadowMap>
|
|
@@ -540,8 +543,14 @@ type ThreeElement<T extends ConstructorRepresentation> = Mutable<
|
|
|
540
543
|
Overwrite<ElementProps<T>, Omit<InstanceProps<InstanceType<T>, T>, 'object'>>
|
|
541
544
|
>
|
|
542
545
|
|
|
546
|
+
/**
|
|
547
|
+
* Every constructor export of a three namespace as an uncapitalized JSX element. Non-constructor
|
|
548
|
+
* exports (constants, functions, nested namespaces) are dropped from the keys rather than mapped
|
|
549
|
+
* to `never`: a single `never`-valued key in `JSX.IntrinsicElements` collapses the props of any
|
|
550
|
+
* tag typed `React.ElementType` (#3898).
|
|
551
|
+
*/
|
|
543
552
|
type ThreeToJSXElements<T extends Record<string, any>> = {
|
|
544
|
-
[K in keyof T & string as
|
|
553
|
+
[K in keyof T & string as T[K] extends ConstructorRepresentation ? Uncapitalize<K> : never]: ThreeElement<T[K]>
|
|
545
554
|
}
|
|
546
555
|
|
|
547
556
|
/** Method names of Object3D, excluded from the `primitive` element's typed props. */
|
|
@@ -2246,16 +2255,67 @@ declare namespace ReactReconciler {
|
|
|
2246
2255
|
): void;
|
|
2247
2256
|
}
|
|
2248
2257
|
|
|
2258
|
+
/**
|
|
2259
|
+
* Registers constructors so they can be rendered as JSX elements.
|
|
2260
|
+
*
|
|
2261
|
+
* - `extend({ OrbitControls })` makes each constructor available under its camelCased key
|
|
2262
|
+
* (`<orbitControls />`). Values that are not constructors are skipped, so a whole module
|
|
2263
|
+
* namespace can be passed.
|
|
2264
|
+
* - `extend(MyClass)` registers one constructor and returns a component to render it with.
|
|
2265
|
+
*
|
|
2266
|
+
* Registrations are global, shared by every copy and entry of fiber, and are checked before the
|
|
2267
|
+
* three namespace of a root's renderer when an element name is resolved.
|
|
2268
|
+
*
|
|
2269
|
+
* @example
|
|
2270
|
+
* import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
|
|
2271
|
+
* extend({ OrbitControls })
|
|
2272
|
+
* // <orbitControls args={[camera, gl.domElement]} />
|
|
2273
|
+
*
|
|
2274
|
+
* @example
|
|
2275
|
+
* const Controls = extend(OrbitControls)
|
|
2276
|
+
* // <Controls args={[camera, gl.domElement]} />
|
|
2277
|
+
*
|
|
2278
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively
|
|
2279
|
+
*/
|
|
2249
2280
|
declare function extend<T extends ConstructorRepresentation>(objects: T): React$1.ExoticComponent<ThreeElement<T>>;
|
|
2281
|
+
/** Registers each constructor in `objects` under its key; see the first overload. */
|
|
2250
2282
|
declare function extend<T extends Catalogue>(objects: T): void;
|
|
2283
|
+
/** Registers every constructor in a module namespace, skipping other exports; see the first overload. */
|
|
2251
2284
|
declare function extend(objects: Record<string, unknown>): void;
|
|
2252
2285
|
|
|
2286
|
+
/**
|
|
2287
|
+
* R3F's React reconciler: a mutation-mode host config that turns JSX elements into three.js objects.
|
|
2288
|
+
* Each root's {@link RootStore} is its container, and children attach to `internal.container`
|
|
2289
|
+
* (a portal's target) or else the root's `scene`.
|
|
2290
|
+
*
|
|
2291
|
+
* - **Element names** resolve through `extend()` registrations first, then the three namespace of
|
|
2292
|
+
* the root's renderer. A `three` prefix (`<threeLine>`) is stripped when no element by the
|
|
2293
|
+
* prefixed name exists. `<primitive object={...}>` wraps an existing object.
|
|
2294
|
+
* - **Construction is deferred** until an instance is attached to a mounted parent, so a tree that
|
|
2295
|
+
* Suspense discards never creates three objects.
|
|
2296
|
+
* - **Updates** apply only changed props. Changing `args` (or a primitive's `object`) reconstructs
|
|
2297
|
+
* the object instead; the swap happens in `resetAfterCommit`, before layout effects, so refs
|
|
2298
|
+
* already point to the new object.
|
|
2299
|
+
* - **Removal** detaches the object and disposes it (at idle priority, or immediately in an `act`
|
|
2300
|
+
* test environment), unless it is a primitive, a `Scene`, or it or an ancestor has `dispose={null}`.
|
|
2301
|
+
* - **Priority**: not the primary renderer, so it runs alongside react-dom, and update priority
|
|
2302
|
+
* follows react-dom's event priorities. View-transition commits are flushed synchronously, since
|
|
2303
|
+
* three has nothing to animate between commits.
|
|
2304
|
+
*
|
|
2305
|
+
* `createRoot`, `createPortal` and `flushSync` drive it; app code rarely needs it directly.
|
|
2306
|
+
*/
|
|
2253
2307
|
declare const reconciler: ReactReconciler.Reconciler<RootStore, Instance<any>, void, Instance<any>, never, any>;
|
|
2254
2308
|
|
|
2255
2309
|
declare const isRenderer: (def: any) => boolean;
|
|
2256
2310
|
interface OffscreenCanvas extends EventTarget {
|
|
2257
2311
|
}
|
|
2258
2312
|
declare const _roots: Map<HTMLCanvasElement | OffscreenCanvas, Root>;
|
|
2313
|
+
/**
|
|
2314
|
+
* Unmount the root on `canvas`. The teardown runs once React has committed the unmount, and waits
|
|
2315
|
+
* for a renderer that is still being created. `callback` runs when the root is gone: after the
|
|
2316
|
+
* teardown, and when it disposed a renderer R3F created whose `dispose()` is async (WebGPURenderer
|
|
2317
|
+
* from three r186), after that dispose has settled.
|
|
2318
|
+
*/
|
|
2259
2319
|
declare function unmountComponentAtNode<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(canvas: TCanvas, callback?: (canvas: TCanvas) => void): void;
|
|
2260
2320
|
declare function createPortal(children: ReactNode, container: THREE.Object3D | RefObject<THREE.Object3D | null> | RefObject<THREE.Object3D>, state?: InjectState): JSX.Element;
|
|
2261
2321
|
interface PortalProps {
|
|
@@ -2272,6 +2332,30 @@ declare function Portal({ children, container, state }: PortalProps): JSX.Elemen
|
|
|
2272
2332
|
*/
|
|
2273
2333
|
declare function flushSync<R>(fn: () => R): R;
|
|
2274
2334
|
|
|
2335
|
+
/**
|
|
2336
|
+
* Creates the Zustand store that holds one root's {@link RootState}.
|
|
2337
|
+
*
|
|
2338
|
+
* The store starts unconfigured: the renderer, `camera`, `scene`, `raycaster`, `frustum` and `pointer`
|
|
2339
|
+
* are `null` placeholders until the root's renderer support has loaded and `configure()` in
|
|
2340
|
+
* `renderer.tsx` fills them in. Only core's part of `RootState` is created here; packages building on
|
|
2341
|
+
* fiber add their own fields through root extensions.
|
|
2342
|
+
*
|
|
2343
|
+
* Besides the initial state, the store wires up:
|
|
2344
|
+
* - `state.gl` and `state.renderer` as accessors over `internal.actualRenderer`. `gl` reports a
|
|
2345
|
+
* deprecation when user code reads it outside legacy mode.
|
|
2346
|
+
* - `rootScene` following `scene` whenever `scene` is set to a real `THREE.Scene`.
|
|
2347
|
+
* - On a size or DPR change: updating the camera and resizing the root's own canvas target (or the
|
|
2348
|
+
* renderer when there is none).
|
|
2349
|
+
* - On a camera change: adding an unparented camera to `rootScene`, then refreshing the viewport and
|
|
2350
|
+
* (when `autoUpdateFrustum` is set) the frustum.
|
|
2351
|
+
* - Calling `invalidate(state)` after every state change.
|
|
2352
|
+
*
|
|
2353
|
+
* `createRoot` calls this once per canvas.
|
|
2354
|
+
*
|
|
2355
|
+
* @param invalidate - Requests frames for a root. Bound into `state.invalidate` and called on every store change.
|
|
2356
|
+
* @param advance - Steps a root manually. Bound into `state.advance`.
|
|
2357
|
+
* @returns The root's store, which is also the reconciler container for that root.
|
|
2358
|
+
*/
|
|
2275
2359
|
declare const createStore: (invalidate: (state?: RootState, frames?: number, stackFrames?: boolean) => void, advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: XRFrame) => void) => RootStore;
|
|
2276
2360
|
|
|
2277
2361
|
/** Whether any root has loaded a renderer yet. */
|