@webspatial/react-sdk 1.2.1 → 1.4.0
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/default/index.d.ts +120 -34
- package/dist/default/index.js +771 -270
- package/dist/default/index.js.map +1 -1
- package/dist/jsx/jsx-dev-runtime.d.ts +2 -1
- package/dist/jsx/jsx-dev-runtime.js +3 -2
- package/dist/jsx/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx/jsx-dev-runtime.web.js +1 -1
- package/dist/jsx/jsx-runtime.js +3 -2
- package/dist/jsx/jsx-runtime.js.map +1 -1
- package/dist/jsx/jsx-runtime.web.js +1 -1
- package/dist/web/index.d.ts +120 -34
- package/dist/web/index.js +784 -270
- package/dist/web/index.js.map +1 -1
- package/package.json +2 -2
package/dist/default/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
(function(){
|
|
3
3
|
if(typeof window === 'undefined') return;
|
|
4
4
|
if(!window.__webspatialsdk__) window.__webspatialsdk__ = {}
|
|
5
|
-
window.__webspatialsdk__['react-sdk-version'] = "1.
|
|
5
|
+
window.__webspatialsdk__['react-sdk-version'] = "1.4.0"
|
|
6
6
|
window.__webspatialsdk__['XR_ENV'] = "avp"
|
|
7
7
|
})()
|
|
8
8
|
|
|
@@ -170,18 +170,12 @@ var SpatialContainerRefProxy = class {
|
|
|
170
170
|
if (prop === "__raw") {
|
|
171
171
|
return target;
|
|
172
172
|
}
|
|
173
|
-
if (prop === "
|
|
173
|
+
if (prop === "xrClientDepth") {
|
|
174
174
|
return target.style.getPropertyValue(SpatialCustomStyleVars.depth);
|
|
175
175
|
}
|
|
176
|
-
if (prop === "
|
|
176
|
+
if (prop === "xrOffsetBack") {
|
|
177
177
|
return target.style.getPropertyValue(SpatialCustomStyleVars.back);
|
|
178
178
|
}
|
|
179
|
-
if (prop === "getBoundingClientRect") {
|
|
180
|
-
return dom.__getBoundingClientRect;
|
|
181
|
-
}
|
|
182
|
-
if (prop === "getBoundingClientCube") {
|
|
183
|
-
return dom.__getBoundingClientCube;
|
|
184
|
-
}
|
|
185
179
|
if (prop === "style") {
|
|
186
180
|
if (!self.styleProxy) {
|
|
187
181
|
self.styleProxy = new Proxy(target.style, {
|
|
@@ -849,7 +843,7 @@ var TransformVisibilityTaskContainer = forwardRef2(
|
|
|
849
843
|
);
|
|
850
844
|
|
|
851
845
|
// src/spatialized-container/SpatializedContainer.tsx
|
|
852
|
-
import { forwardRef as forwardRef4, useContext as
|
|
846
|
+
import { forwardRef as forwardRef4, useContext as useContext7, useEffect as useEffect10, useMemo as useMemo2 } from "react";
|
|
853
847
|
|
|
854
848
|
// src/utils/getSession.ts
|
|
855
849
|
import { isSSREnv, Spatial } from "@webspatial/core-sdk";
|
|
@@ -897,37 +891,6 @@ function enableDebugTool() {
|
|
|
897
891
|
});
|
|
898
892
|
}
|
|
899
893
|
|
|
900
|
-
// src/spatialized-container/transform-utils.ts
|
|
901
|
-
function toSceneSpatial(point, spatializedElement) {
|
|
902
|
-
return spatializedElement.__toSceneSpace(point);
|
|
903
|
-
}
|
|
904
|
-
function toLocalSpace(point, spatializedElement) {
|
|
905
|
-
return spatializedElement.__toLocalSpace(point);
|
|
906
|
-
}
|
|
907
|
-
function convertDOMRectToSceneSpace(originalRect, matrix) {
|
|
908
|
-
const topLeft = new DOMPoint(originalRect.left, originalRect.top);
|
|
909
|
-
const topRight = new DOMPoint(originalRect.right, originalRect.top);
|
|
910
|
-
const bottomRight = new DOMPoint(originalRect.right, originalRect.bottom);
|
|
911
|
-
const bottomLeft = new DOMPoint(originalRect.left, originalRect.bottom);
|
|
912
|
-
const transformedTopLeft = matrix.transformPoint(topLeft);
|
|
913
|
-
const transformedTopRight = matrix.transformPoint(topRight);
|
|
914
|
-
const transformedBottomRight = matrix.transformPoint(bottomRight);
|
|
915
|
-
const transformedBottomLeft = matrix.transformPoint(bottomLeft);
|
|
916
|
-
const allPoints = [
|
|
917
|
-
transformedTopLeft,
|
|
918
|
-
transformedTopRight,
|
|
919
|
-
transformedBottomRight,
|
|
920
|
-
transformedBottomLeft
|
|
921
|
-
];
|
|
922
|
-
const xCoords = allPoints.map((point) => point.x);
|
|
923
|
-
const yCoords = allPoints.map((point) => point.y);
|
|
924
|
-
const newMinX = Math.min(...xCoords);
|
|
925
|
-
const newMaxX = Math.max(...xCoords);
|
|
926
|
-
const newMinY = Math.min(...yCoords);
|
|
927
|
-
const newMaxY = Math.max(...yCoords);
|
|
928
|
-
return new DOMRect(newMinX, newMinY, newMaxX - newMinX, newMaxY - newMinY);
|
|
929
|
-
}
|
|
930
|
-
|
|
931
894
|
// src/spatialized-container/context/PortalInstanceContext.ts
|
|
932
895
|
var PortalInstanceObject = class {
|
|
933
896
|
spatialId;
|
|
@@ -1012,40 +975,8 @@ var PortalInstanceObject = class {
|
|
|
1012
975
|
isFixedPosition: computedStyle.getPropertyValue("position") === "fixed"
|
|
1013
976
|
};
|
|
1014
977
|
this.updateSpatializedElementProperties();
|
|
1015
|
-
const __getBoundingClientCube = () => {
|
|
1016
|
-
return this.spatializedElement?.cubeInfo;
|
|
1017
|
-
};
|
|
1018
|
-
const __getBoundingClientRect = () => {
|
|
1019
|
-
if (!this.spatializedElement?.transform) {
|
|
1020
|
-
return null;
|
|
1021
|
-
}
|
|
1022
|
-
const domRect = new DOMRect(
|
|
1023
|
-
0,
|
|
1024
|
-
0,
|
|
1025
|
-
this.domRect?.width,
|
|
1026
|
-
this.domRect?.height
|
|
1027
|
-
);
|
|
1028
|
-
return convertDOMRectToSceneSpace(
|
|
1029
|
-
domRect,
|
|
1030
|
-
this.spatializedElement?.transform
|
|
1031
|
-
);
|
|
1032
|
-
};
|
|
1033
|
-
const __toSceneSpace = (point) => {
|
|
1034
|
-
return new DOMPoint(point.x, point.y, point.z).matrixTransform(
|
|
1035
|
-
this.spatializedElement?.transform
|
|
1036
|
-
);
|
|
1037
|
-
};
|
|
1038
|
-
const __toLocalSpace = (point) => {
|
|
1039
|
-
return new DOMPoint(point.x, point.y, point.z).matrixTransform(
|
|
1040
|
-
this.spatializedElement?.transformInv
|
|
1041
|
-
);
|
|
1042
|
-
};
|
|
1043
978
|
const __innerSpatializedElement = () => this.spatializedElement;
|
|
1044
979
|
Object.assign(dom, {
|
|
1045
|
-
__getBoundingClientCube,
|
|
1046
|
-
__getBoundingClientRect,
|
|
1047
|
-
__toSceneSpace,
|
|
1048
|
-
__toLocalSpace,
|
|
1049
980
|
__innerSpatializedElement
|
|
1050
981
|
});
|
|
1051
982
|
}
|
|
@@ -1163,18 +1094,19 @@ function useSync2DFrame(spatialId, portalInstanceObject, spatializedContainerObj
|
|
|
1163
1094
|
}
|
|
1164
1095
|
|
|
1165
1096
|
// src/spatialized-container/hooks/useSpatializedElement.ts
|
|
1166
|
-
import { useEffect as useEffect6, useState as useState3 } from "react";
|
|
1097
|
+
import { useEffect as useEffect6, useRef as useRef4, useState as useState3 } from "react";
|
|
1167
1098
|
function useSpatializedElement(createSpatializedElement2, portalInstanceObject) {
|
|
1168
1099
|
const [spatializedElement, setSpatializedElement] = useState3();
|
|
1100
|
+
const elementRef = useRef4(void 0);
|
|
1169
1101
|
useEffect6(() => {
|
|
1170
1102
|
let isDestroyed = false;
|
|
1171
|
-
let spatializedElement2;
|
|
1172
1103
|
createSpatializedElement2().then(
|
|
1173
1104
|
(inSpatializedElement) => {
|
|
1105
|
+
if (!inSpatializedElement) return;
|
|
1174
1106
|
if (!isDestroyed) {
|
|
1175
|
-
|
|
1176
|
-
portalInstanceObject.attachSpatializedElement(
|
|
1177
|
-
setSpatializedElement(
|
|
1107
|
+
elementRef.current = inSpatializedElement;
|
|
1108
|
+
portalInstanceObject.attachSpatializedElement(inSpatializedElement);
|
|
1109
|
+
setSpatializedElement(inSpatializedElement);
|
|
1178
1110
|
} else {
|
|
1179
1111
|
inSpatializedElement?.destroy();
|
|
1180
1112
|
}
|
|
@@ -1182,9 +1114,11 @@ function useSpatializedElement(createSpatializedElement2, portalInstanceObject)
|
|
|
1182
1114
|
);
|
|
1183
1115
|
return () => {
|
|
1184
1116
|
isDestroyed = true;
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1117
|
+
const el = elementRef.current;
|
|
1118
|
+
if (el) {
|
|
1119
|
+
el.destroy();
|
|
1120
|
+
elementRef.current = void 0;
|
|
1121
|
+
setSpatializedElement(void 0);
|
|
1188
1122
|
}
|
|
1189
1123
|
};
|
|
1190
1124
|
}, [createSpatializedElement2, portalInstanceObject]);
|
|
@@ -1193,6 +1127,18 @@ function useSpatializedElement(createSpatializedElement2, portalInstanceObject)
|
|
|
1193
1127
|
|
|
1194
1128
|
// src/spatialized-container/PortalSpatializedContainer.tsx
|
|
1195
1129
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
1130
|
+
function constrainedAxisToVec3(input) {
|
|
1131
|
+
if (input == null) return { x: 0, y: 0, z: 0 };
|
|
1132
|
+
if (Array.isArray(input)) {
|
|
1133
|
+
return { x: input[0] ?? 0, y: input[1] ?? 0, z: input[2] ?? 0 };
|
|
1134
|
+
}
|
|
1135
|
+
const v = input;
|
|
1136
|
+
return { x: v.x, y: v.y, z: v.z };
|
|
1137
|
+
}
|
|
1138
|
+
function constrainedAxisKey(input) {
|
|
1139
|
+
const v = constrainedAxisToVec3(input);
|
|
1140
|
+
return `${v.x},${v.y},${v.z}`;
|
|
1141
|
+
}
|
|
1196
1142
|
function renderPlaceholderInSubPortal(portalInstanceObject, El) {
|
|
1197
1143
|
const spatialId = portalInstanceObject.spatialId;
|
|
1198
1144
|
const inPortalInstanceEnv = !!portalInstanceObject.parentPortalInstanceObject;
|
|
@@ -1231,6 +1177,7 @@ function PortalSpatializedContainer(props) {
|
|
|
1231
1177
|
onSpatialRotateEnd,
|
|
1232
1178
|
onSpatialMagnify,
|
|
1233
1179
|
onSpatialMagnifyEnd,
|
|
1180
|
+
spatialEventOptions,
|
|
1234
1181
|
[SpatialID]: spatialId,
|
|
1235
1182
|
...restProps
|
|
1236
1183
|
} = props;
|
|
@@ -1302,14 +1249,27 @@ function PortalSpatializedContainer(props) {
|
|
|
1302
1249
|
spatializedElement.onSpatialDragStart = onSpatialDragStart;
|
|
1303
1250
|
}
|
|
1304
1251
|
}, [spatializedElement, onSpatialDragStart]);
|
|
1252
|
+
const rotateConstraintKey = constrainedAxisKey(
|
|
1253
|
+
spatialEventOptions?.constrainedToAxis
|
|
1254
|
+
);
|
|
1255
|
+
useEffect7(() => {
|
|
1256
|
+
if (!spatializedElement) return;
|
|
1257
|
+
const axis = constrainedAxisToVec3(spatialEventOptions?.constrainedToAxis);
|
|
1258
|
+
void spatializedElement.updateProperties({ rotateConstrainedToAxis: axis });
|
|
1259
|
+
}, [spatializedElement, rotateConstraintKey]);
|
|
1305
1260
|
return /* @__PURE__ */ jsxs(PortalInstanceContext.Provider, { value: portalInstanceObject, children: [
|
|
1306
1261
|
spatializedElement && portalInstanceObject.dom && /* @__PURE__ */ jsx3(Content, { spatializedElement, ...restProps }),
|
|
1307
1262
|
PlaceholderEl
|
|
1308
1263
|
] });
|
|
1309
1264
|
}
|
|
1310
1265
|
|
|
1266
|
+
// src/reality/context/InsideAttachmentContext.tsx
|
|
1267
|
+
import { createContext as createContext4, useContext as useContext5 } from "react";
|
|
1268
|
+
var InsideAttachmentContext = createContext4(false);
|
|
1269
|
+
var useInsideAttachment = () => useContext5(InsideAttachmentContext);
|
|
1270
|
+
|
|
1311
1271
|
// src/spatialized-container/hooks/useSpatialEvents.ts
|
|
1312
|
-
function createEventProxy(event, currentTargetGetter, offsetXGetter, offsetYGetter, offsetZGetter) {
|
|
1272
|
+
function createEventProxy(event, currentTargetGetter, offsetXGetter, offsetYGetter, offsetZGetter, clientXGetter, clientYGetter, clientZGetter, translationXGetter, translationYGetter, translationZGetter, quaternionGetter, magnificationGetter) {
|
|
1313
1273
|
return new Proxy(event, {
|
|
1314
1274
|
get(target, prop) {
|
|
1315
1275
|
if (prop === "currentTarget") {
|
|
@@ -1330,18 +1290,50 @@ function createEventProxy(event, currentTargetGetter, offsetXGetter, offsetYGett
|
|
|
1330
1290
|
if (prop === "offsetZ" && offsetZGetter) {
|
|
1331
1291
|
return offsetZGetter(target) ?? 0;
|
|
1332
1292
|
}
|
|
1293
|
+
if (prop === "clientX" && clientXGetter) {
|
|
1294
|
+
return clientXGetter(target) ?? 0;
|
|
1295
|
+
}
|
|
1296
|
+
if (prop === "clientY" && clientYGetter) {
|
|
1297
|
+
return clientYGetter(target) ?? 0;
|
|
1298
|
+
}
|
|
1299
|
+
if (prop === "clientZ" && clientZGetter) {
|
|
1300
|
+
return clientZGetter(target) ?? 0;
|
|
1301
|
+
}
|
|
1302
|
+
if (prop === "translationX" && translationXGetter) {
|
|
1303
|
+
return translationXGetter(target) ?? 0;
|
|
1304
|
+
}
|
|
1305
|
+
if (prop === "translationY" && translationYGetter) {
|
|
1306
|
+
return translationYGetter(target) ?? 0;
|
|
1307
|
+
}
|
|
1308
|
+
if (prop === "translationZ" && translationZGetter) {
|
|
1309
|
+
return translationZGetter(target) ?? 0;
|
|
1310
|
+
}
|
|
1311
|
+
if (prop === "quaternion" && quaternionGetter) {
|
|
1312
|
+
return quaternionGetter(target) ?? { x: 0, y: 0, z: 0, w: 1 };
|
|
1313
|
+
}
|
|
1314
|
+
if (prop === "magnification" && magnificationGetter) {
|
|
1315
|
+
return magnificationGetter(target) ?? 1;
|
|
1316
|
+
}
|
|
1333
1317
|
return Reflect.get(target, prop);
|
|
1334
1318
|
}
|
|
1335
1319
|
});
|
|
1336
1320
|
}
|
|
1337
|
-
function createEventHandler(handler, currentTargetGetter, offsetXGetter, offsetYGetter, offsetZGetter) {
|
|
1321
|
+
function createEventHandler(handler, currentTargetGetter, offsetXGetter, offsetYGetter, offsetZGetter, clientXGetter, clientYGetter, clientZGetter, translationXGetter, translationYGetter, translationZGetter, quaternionGetter, magnificationGetter) {
|
|
1338
1322
|
return handler ? (event) => {
|
|
1339
1323
|
const proxyEvent = createEventProxy(
|
|
1340
1324
|
event,
|
|
1341
1325
|
currentTargetGetter,
|
|
1342
1326
|
offsetXGetter,
|
|
1343
1327
|
offsetYGetter,
|
|
1344
|
-
offsetZGetter
|
|
1328
|
+
offsetZGetter,
|
|
1329
|
+
clientXGetter,
|
|
1330
|
+
clientYGetter,
|
|
1331
|
+
clientZGetter,
|
|
1332
|
+
translationXGetter,
|
|
1333
|
+
translationYGetter,
|
|
1334
|
+
translationZGetter,
|
|
1335
|
+
quaternionGetter,
|
|
1336
|
+
magnificationGetter
|
|
1345
1337
|
);
|
|
1346
1338
|
handler(proxyEvent);
|
|
1347
1339
|
} : void 0;
|
|
@@ -1350,13 +1342,27 @@ function useSpatialEventsBase(spatialEvents, currentTargetGetter) {
|
|
|
1350
1342
|
const onSpatialTap = createEventHandler(
|
|
1351
1343
|
spatialEvents.onSpatialTap,
|
|
1352
1344
|
currentTargetGetter,
|
|
1345
|
+
// offsetX/Y/Z come from local coordinates
|
|
1353
1346
|
(ev) => ev.detail?.location3D?.x,
|
|
1354
1347
|
(ev) => ev.detail?.location3D?.y,
|
|
1355
|
-
(ev) => ev.detail?.location3D?.z
|
|
1348
|
+
(ev) => ev.detail?.location3D?.z,
|
|
1349
|
+
// clientX/Y/Z come from global scene coordinates
|
|
1350
|
+
(ev) => ev.detail?.globalLocation3D?.x,
|
|
1351
|
+
(ev) => ev.detail?.globalLocation3D?.y,
|
|
1352
|
+
(ev) => ev.detail?.globalLocation3D?.z
|
|
1356
1353
|
);
|
|
1357
1354
|
const onSpatialDrag = createEventHandler(
|
|
1358
1355
|
spatialEvents.onSpatialDrag,
|
|
1359
|
-
currentTargetGetter
|
|
1356
|
+
currentTargetGetter,
|
|
1357
|
+
void 0,
|
|
1358
|
+
void 0,
|
|
1359
|
+
void 0,
|
|
1360
|
+
void 0,
|
|
1361
|
+
void 0,
|
|
1362
|
+
void 0,
|
|
1363
|
+
(ev) => ev.detail?.translation3D?.x,
|
|
1364
|
+
(ev) => ev.detail?.translation3D?.y,
|
|
1365
|
+
(ev) => ev.detail?.translation3D?.z
|
|
1360
1366
|
);
|
|
1361
1367
|
const onSpatialDragEnd = createEventHandler(
|
|
1362
1368
|
spatialEvents.onSpatialDragEnd,
|
|
@@ -1364,7 +1370,17 @@ function useSpatialEventsBase(spatialEvents, currentTargetGetter) {
|
|
|
1364
1370
|
);
|
|
1365
1371
|
const onSpatialRotate = createEventHandler(
|
|
1366
1372
|
spatialEvents.onSpatialRotate,
|
|
1367
|
-
currentTargetGetter
|
|
1373
|
+
currentTargetGetter,
|
|
1374
|
+
void 0,
|
|
1375
|
+
void 0,
|
|
1376
|
+
void 0,
|
|
1377
|
+
void 0,
|
|
1378
|
+
void 0,
|
|
1379
|
+
void 0,
|
|
1380
|
+
void 0,
|
|
1381
|
+
void 0,
|
|
1382
|
+
void 0,
|
|
1383
|
+
(ev) => ev.detail?.quaternion
|
|
1368
1384
|
);
|
|
1369
1385
|
const onSpatialRotateEnd = createEventHandler(
|
|
1370
1386
|
spatialEvents.onSpatialRotateEnd,
|
|
@@ -1372,7 +1388,18 @@ function useSpatialEventsBase(spatialEvents, currentTargetGetter) {
|
|
|
1372
1388
|
);
|
|
1373
1389
|
const onSpatialMagnify = createEventHandler(
|
|
1374
1390
|
spatialEvents.onSpatialMagnify,
|
|
1375
|
-
currentTargetGetter
|
|
1391
|
+
currentTargetGetter,
|
|
1392
|
+
void 0,
|
|
1393
|
+
void 0,
|
|
1394
|
+
void 0,
|
|
1395
|
+
void 0,
|
|
1396
|
+
void 0,
|
|
1397
|
+
void 0,
|
|
1398
|
+
void 0,
|
|
1399
|
+
void 0,
|
|
1400
|
+
void 0,
|
|
1401
|
+
void 0,
|
|
1402
|
+
(ev) => ev.detail?.magnification
|
|
1376
1403
|
);
|
|
1377
1404
|
const onSpatialMagnifyEnd = createEventHandler(
|
|
1378
1405
|
spatialEvents.onSpatialMagnifyEnd,
|
|
@@ -1383,7 +1410,10 @@ function useSpatialEventsBase(spatialEvents, currentTargetGetter) {
|
|
|
1383
1410
|
currentTargetGetter,
|
|
1384
1411
|
(ev) => ev.detail?.startLocation3D?.x,
|
|
1385
1412
|
(ev) => ev.detail?.startLocation3D?.y,
|
|
1386
|
-
(ev) => ev.detail?.startLocation3D?.z
|
|
1413
|
+
(ev) => ev.detail?.startLocation3D?.z,
|
|
1414
|
+
(ev) => ev.detail?.globalLocation3D?.x,
|
|
1415
|
+
(ev) => ev.detail?.globalLocation3D?.y,
|
|
1416
|
+
(ev) => ev.detail?.globalLocation3D?.z
|
|
1387
1417
|
);
|
|
1388
1418
|
return {
|
|
1389
1419
|
onSpatialTap,
|
|
@@ -1412,9 +1442,9 @@ function useSpatialEventsWhenSpatializedContainerExist(spatialEvents, spatialId,
|
|
|
1412
1442
|
}
|
|
1413
1443
|
|
|
1414
1444
|
// src/ssr/SSRContext.tsx
|
|
1415
|
-
import { createContext as
|
|
1445
|
+
import { createContext as createContext5, useState as useState4, useEffect as useEffect8 } from "react";
|
|
1416
1446
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1417
|
-
var SSRContext =
|
|
1447
|
+
var SSRContext = createContext5(false);
|
|
1418
1448
|
var SSRProvider = ({
|
|
1419
1449
|
isSSR: initialIsSSR = true,
|
|
1420
1450
|
children
|
|
@@ -1432,9 +1462,9 @@ var SSRProvider = ({
|
|
|
1432
1462
|
import { forwardRef as forwardRef3 } from "react";
|
|
1433
1463
|
|
|
1434
1464
|
// src/ssr/useSSRPhase.tsx
|
|
1435
|
-
import { useContext as
|
|
1465
|
+
import { useContext as useContext6, useState as useState5, useEffect as useEffect9 } from "react";
|
|
1436
1466
|
function useSSRPhase() {
|
|
1437
|
-
const isSSRContext =
|
|
1467
|
+
const isSSRContext = useContext6(SSRContext);
|
|
1438
1468
|
const isServer = typeof window === "undefined";
|
|
1439
1469
|
const [hydrated, setHydrated] = useState5(false);
|
|
1440
1470
|
useEffect9(() => setHydrated(true), []);
|
|
@@ -1470,33 +1500,49 @@ function withSSRSupported(Component) {
|
|
|
1470
1500
|
|
|
1471
1501
|
// src/spatialized-container/SpatializedContainer.tsx
|
|
1472
1502
|
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1503
|
+
function DegradedContainer({
|
|
1504
|
+
innerRef,
|
|
1505
|
+
...inprops
|
|
1506
|
+
}) {
|
|
1507
|
+
const {
|
|
1508
|
+
component: Component,
|
|
1509
|
+
children,
|
|
1510
|
+
["enable-xr"]: _enableXR,
|
|
1511
|
+
onSpatialTap: _onSpatialTap,
|
|
1512
|
+
onSpatialDragStart: _onSpatialDragStart,
|
|
1513
|
+
onSpatialDrag: _onSpatialDrag,
|
|
1514
|
+
onSpatialDragEnd: _onSpatialDragEnd,
|
|
1515
|
+
onSpatialRotate: _onSpatialRotate,
|
|
1516
|
+
onSpatialRotateEnd: _onSpatialRotateEnd,
|
|
1517
|
+
onSpatialMagnify: _onSpatialMagnify,
|
|
1518
|
+
onSpatialMagnifyEnd: _onSpatialMagnifyEnd,
|
|
1519
|
+
spatialEventOptions: _spatialEventOptions,
|
|
1520
|
+
spatializedContent: _content,
|
|
1521
|
+
createSpatializedElement: _create,
|
|
1522
|
+
getExtraSpatializedElementProperties: _getExtra,
|
|
1523
|
+
extraRefProps: _extraRef,
|
|
1524
|
+
sizingMode: _sizingMode,
|
|
1525
|
+
...restProps
|
|
1526
|
+
} = inprops;
|
|
1527
|
+
return /* @__PURE__ */ jsx6(Component, { ref: innerRef, ...restProps, children });
|
|
1528
|
+
}
|
|
1473
1529
|
function SpatializedContainerBase(inprops, ref) {
|
|
1474
1530
|
const isWebSpatialEnv = getSession() !== null;
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
onSpatialDrag: onSpatialDrag2,
|
|
1484
|
-
onSpatialDragEnd: onSpatialDragEnd2,
|
|
1485
|
-
onSpatialRotate: onSpatialRotate2,
|
|
1486
|
-
onSpatialRotateEnd: onSpatialRotateEnd2,
|
|
1487
|
-
onSpatialMagnify: onSpatialMagnify2,
|
|
1488
|
-
onSpatialMagnifyEnd: onSpatialMagnifyEnd2,
|
|
1489
|
-
extraRefProps: extraRefProps2,
|
|
1490
|
-
...restProps
|
|
1491
|
-
} = inprops;
|
|
1492
|
-
return /* @__PURE__ */ jsx6(Component, { ref, ...restProps });
|
|
1531
|
+
const insideAttachment = useInsideAttachment();
|
|
1532
|
+
if (!isWebSpatialEnv || insideAttachment) {
|
|
1533
|
+
if (insideAttachment) {
|
|
1534
|
+
console.warn(
|
|
1535
|
+
`[WebSpatial] ${inprops.component || "Spatial element"} cannot be used inside AttachmentAsset. Rendering as plain HTML.`
|
|
1536
|
+
);
|
|
1537
|
+
}
|
|
1538
|
+
return /* @__PURE__ */ jsx6(DegradedContainer, { ...inprops, innerRef: ref });
|
|
1493
1539
|
}
|
|
1494
|
-
const layer =
|
|
1495
|
-
const rootSpatializedContainerObject =
|
|
1540
|
+
const layer = useContext7(SpatialLayerContext) + 1;
|
|
1541
|
+
const rootSpatializedContainerObject = useContext7(
|
|
1496
1542
|
SpatializedContainerContext
|
|
1497
1543
|
);
|
|
1498
1544
|
const inSpatializedContainer = !!rootSpatializedContainerObject;
|
|
1499
|
-
const portalInstanceObject =
|
|
1545
|
+
const portalInstanceObject = useContext7(PortalInstanceContext);
|
|
1500
1546
|
const inPortalInstanceEnv = !!portalInstanceObject;
|
|
1501
1547
|
const isInStandardInstance = !inPortalInstanceEnv;
|
|
1502
1548
|
const spatialId = useMemo2(() => {
|
|
@@ -1557,6 +1603,7 @@ function SpatializedContainerBase(inprops, ref) {
|
|
|
1557
1603
|
spatializedContent,
|
|
1558
1604
|
createSpatializedElement: createSpatializedElement2,
|
|
1559
1605
|
getExtraSpatializedElementProperties: getExtraSpatializedElementProperties2,
|
|
1606
|
+
spatialEventOptions: _nestedSpatialEventOptions,
|
|
1560
1607
|
...restProps
|
|
1561
1608
|
} = props;
|
|
1562
1609
|
return /* @__PURE__ */ jsxs2(SpatialLayerContext.Provider, { value: layer, children: [
|
|
@@ -1607,6 +1654,7 @@ function SpatializedContainerBase(inprops, ref) {
|
|
|
1607
1654
|
spatializedContent,
|
|
1608
1655
|
createSpatializedElement: createSpatializedElement2,
|
|
1609
1656
|
getExtraSpatializedElementProperties: getExtraSpatializedElementProperties2,
|
|
1657
|
+
spatialEventOptions: _rootSpatialEventOptions,
|
|
1610
1658
|
...restProps
|
|
1611
1659
|
} = props;
|
|
1612
1660
|
return /* @__PURE__ */ jsx6(SpatialLayerContext.Provider, { value: layer, children: /* @__PURE__ */ jsxs2(
|
|
@@ -1650,28 +1698,47 @@ var SpatializedContainer = withSSRSupported(
|
|
|
1650
1698
|
);
|
|
1651
1699
|
|
|
1652
1700
|
// src/spatialized-container/Spatialized2DElementContainer.tsx
|
|
1701
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1653
1702
|
import {
|
|
1654
1703
|
forwardRef as forwardRef5,
|
|
1655
|
-
useContext as
|
|
1656
|
-
useEffect as
|
|
1704
|
+
useContext as useContext8,
|
|
1705
|
+
useEffect as useEffect12
|
|
1657
1706
|
} from "react";
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
function asyncLoadStyleToChildWindow(childWindow,
|
|
1707
|
+
|
|
1708
|
+
// src/utils/windowStyleSync.ts
|
|
1709
|
+
function asyncLoadStyleToChildWindow(childWindow, link, isCurrent) {
|
|
1661
1710
|
return new Promise((resolve) => {
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1711
|
+
const { href } = link;
|
|
1712
|
+
const sep = href.includes("?") ? "&" : "?";
|
|
1713
|
+
link.href = `${href}${sep}uniqueURL=${Math.random()}`;
|
|
1714
|
+
let finished = false;
|
|
1715
|
+
const finish = (ok) => {
|
|
1716
|
+
if (finished) return;
|
|
1717
|
+
finished = true;
|
|
1718
|
+
resolve(ok);
|
|
1719
|
+
};
|
|
1720
|
+
link.onerror = () => {
|
|
1721
|
+
finish(false);
|
|
1666
1722
|
};
|
|
1667
|
-
|
|
1668
|
-
|
|
1723
|
+
link.onload = () => {
|
|
1724
|
+
if (!isCurrent()) {
|
|
1725
|
+
link.parentNode?.removeChild(link);
|
|
1726
|
+
finish(false);
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
finish(true);
|
|
1669
1730
|
};
|
|
1670
1731
|
setTimeout(() => {
|
|
1671
|
-
|
|
1732
|
+
if (!isCurrent()) {
|
|
1733
|
+
finish(false);
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
childWindow.document.head.appendChild(link);
|
|
1672
1737
|
}, 50);
|
|
1673
1738
|
});
|
|
1674
1739
|
}
|
|
1740
|
+
var WEBSPATIAL_SYNC_ATTR = "data-webspatial-sync";
|
|
1741
|
+
var WEBSPATIAL_SYNC_KEY_ATTR = "data-webspatial-sync-key";
|
|
1675
1742
|
function setOpenWindowStyle(openedWindow) {
|
|
1676
1743
|
openedWindow.document.documentElement.style.cssText += document.documentElement.style.cssText;
|
|
1677
1744
|
openedWindow.document.documentElement.style.backgroundColor = "transparent";
|
|
@@ -1683,23 +1750,118 @@ function setOpenWindowStyle(openedWindow) {
|
|
|
1683
1750
|
openedWindow.document.body.style.minWidth = "fit-content";
|
|
1684
1751
|
openedWindow.document.body.style.background = "transparent";
|
|
1685
1752
|
}
|
|
1753
|
+
var controllers = /* @__PURE__ */ new WeakMap();
|
|
1754
|
+
function getController(childWindow) {
|
|
1755
|
+
const prev = controllers.get(childWindow);
|
|
1756
|
+
if (prev) return prev;
|
|
1757
|
+
const next = { version: 0 };
|
|
1758
|
+
controllers.set(childWindow, next);
|
|
1759
|
+
return next;
|
|
1760
|
+
}
|
|
1686
1761
|
async function syncParentHeadToChild(childWindow) {
|
|
1762
|
+
const controller = getController(childWindow);
|
|
1763
|
+
const version2 = ++controller.version;
|
|
1687
1764
|
const styleLoadedPromises = [];
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1765
|
+
const { head } = childWindow.document;
|
|
1766
|
+
const isCurrent = () => controller.version === version2;
|
|
1767
|
+
const parentStyles = Array.from(document.head.querySelectorAll("style"));
|
|
1768
|
+
const parentStylesheets = Array.from(
|
|
1769
|
+
document.head.querySelectorAll('link[rel="stylesheet"][href]')
|
|
1770
|
+
);
|
|
1771
|
+
const desiredStylesheetKeys = /* @__PURE__ */ new Set();
|
|
1772
|
+
for (const link of parentStylesheets) {
|
|
1773
|
+
if (link.href) desiredStylesheetKeys.add(link.href);
|
|
1774
|
+
}
|
|
1775
|
+
const existingSyncedLinks = Array.from(
|
|
1776
|
+
head.querySelectorAll(
|
|
1777
|
+
`link[rel="stylesheet"][${WEBSPATIAL_SYNC_ATTR}="1"]`
|
|
1778
|
+
)
|
|
1779
|
+
);
|
|
1780
|
+
for (const link of existingSyncedLinks) {
|
|
1781
|
+
const key = link.getAttribute(WEBSPATIAL_SYNC_KEY_ATTR) ?? link.href;
|
|
1782
|
+
if (!desiredStylesheetKeys.has(key)) link.parentNode?.removeChild(link);
|
|
1783
|
+
}
|
|
1784
|
+
const prevSyncedStyles = head.querySelectorAll(
|
|
1785
|
+
`style[${WEBSPATIAL_SYNC_ATTR}="1"]`
|
|
1786
|
+
);
|
|
1787
|
+
prevSyncedStyles.forEach((n) => n.parentNode?.removeChild(n));
|
|
1788
|
+
for (const styleEl of parentStyles) {
|
|
1789
|
+
const node = styleEl.cloneNode(true);
|
|
1790
|
+
node.setAttribute(WEBSPATIAL_SYNC_ATTR, "1");
|
|
1791
|
+
head.appendChild(node);
|
|
1792
|
+
}
|
|
1793
|
+
const currentKeys = /* @__PURE__ */ new Set();
|
|
1794
|
+
const currentSyncedLinks = Array.from(
|
|
1795
|
+
head.querySelectorAll(
|
|
1796
|
+
`link[rel="stylesheet"][${WEBSPATIAL_SYNC_ATTR}="1"]`
|
|
1797
|
+
)
|
|
1798
|
+
);
|
|
1799
|
+
for (const link of currentSyncedLinks) {
|
|
1800
|
+
currentKeys.add(link.getAttribute(WEBSPATIAL_SYNC_KEY_ATTR) ?? link.href);
|
|
1801
|
+
}
|
|
1802
|
+
for (const link of parentStylesheets) {
|
|
1803
|
+
const key = link.href;
|
|
1804
|
+
if (!key || currentKeys.has(key)) continue;
|
|
1805
|
+
const node = link.cloneNode(true);
|
|
1806
|
+
node.setAttribute(WEBSPATIAL_SYNC_ATTR, "1");
|
|
1807
|
+
node.setAttribute(WEBSPATIAL_SYNC_KEY_ATTR, key);
|
|
1808
|
+
styleLoadedPromises.push(
|
|
1809
|
+
asyncLoadStyleToChildWindow(childWindow, node, isCurrent)
|
|
1810
|
+
);
|
|
1699
1811
|
}
|
|
1700
1812
|
childWindow.document.documentElement.className = document.documentElement.className;
|
|
1701
1813
|
return Promise.all(styleLoadedPromises);
|
|
1702
1814
|
}
|
|
1815
|
+
|
|
1816
|
+
// src/utils/useSyncHeadStyles.ts
|
|
1817
|
+
import { useEffect as useEffect11 } from "react";
|
|
1818
|
+
function defaultShouldSync(mutations) {
|
|
1819
|
+
if (!Array.isArray(mutations) || mutations.length === 0) return false;
|
|
1820
|
+
for (const mutation of mutations) {
|
|
1821
|
+
const nodes = [
|
|
1822
|
+
...Array.from(mutation.addedNodes),
|
|
1823
|
+
...Array.from(mutation.removedNodes)
|
|
1824
|
+
];
|
|
1825
|
+
for (const node of nodes) {
|
|
1826
|
+
if (!(node instanceof Element)) continue;
|
|
1827
|
+
const tag = node.tagName;
|
|
1828
|
+
if (tag === "STYLE") return true;
|
|
1829
|
+
if (tag === "LINK") {
|
|
1830
|
+
const { rel } = node;
|
|
1831
|
+
if (rel && rel.toLowerCase() === "stylesheet") return true;
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
return false;
|
|
1836
|
+
}
|
|
1837
|
+
function useSyncHeadStyles(childWindow, options) {
|
|
1838
|
+
const delayMs = 100;
|
|
1839
|
+
const subtree = options?.subtree ?? false;
|
|
1840
|
+
const immediate = options?.immediate ?? true;
|
|
1841
|
+
useEffect11(() => {
|
|
1842
|
+
if (!childWindow) return;
|
|
1843
|
+
let timer;
|
|
1844
|
+
const scheduleSync = () => {
|
|
1845
|
+
if (timer) window.clearTimeout(timer);
|
|
1846
|
+
timer = window.setTimeout(() => {
|
|
1847
|
+
syncParentHeadToChild(childWindow);
|
|
1848
|
+
}, delayMs);
|
|
1849
|
+
};
|
|
1850
|
+
if (immediate) scheduleSync();
|
|
1851
|
+
const observer = new MutationObserver((mutations) => {
|
|
1852
|
+
if (!defaultShouldSync(mutations)) return;
|
|
1853
|
+
scheduleSync();
|
|
1854
|
+
});
|
|
1855
|
+
observer.observe(document.head, { childList: true, subtree });
|
|
1856
|
+
return () => {
|
|
1857
|
+
if (timer) window.clearTimeout(timer);
|
|
1858
|
+
observer.disconnect();
|
|
1859
|
+
};
|
|
1860
|
+
}, [childWindow, delayMs, subtree, immediate]);
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
// src/spatialized-container/Spatialized2DElementContainer.tsx
|
|
1864
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1703
1865
|
function getJSXPortalInstance(inProps, portalInstanceObject) {
|
|
1704
1866
|
const { component: El, style: inStyle = {}, ...props } = inProps;
|
|
1705
1867
|
const extraStyle = {
|
|
@@ -1725,19 +1887,8 @@ function getJSXPortalInstance(inProps, portalInstanceObject) {
|
|
|
1725
1887
|
};
|
|
1726
1888
|
return /* @__PURE__ */ jsx7(El, { style, ...props });
|
|
1727
1889
|
}
|
|
1728
|
-
function useSyncHeaderStyle(windowProxy) {
|
|
1729
|
-
useEffect11(() => {
|
|
1730
|
-
const headObserver = new MutationObserver((_) => {
|
|
1731
|
-
syncParentHeadToChild(windowProxy);
|
|
1732
|
-
});
|
|
1733
|
-
headObserver.observe(document.head, { childList: true, subtree: true });
|
|
1734
|
-
return () => {
|
|
1735
|
-
headObserver.disconnect();
|
|
1736
|
-
};
|
|
1737
|
-
}, []);
|
|
1738
|
-
}
|
|
1739
1890
|
function useSyncDocumentTitle(windowProxy, spatializedElement, name) {
|
|
1740
|
-
|
|
1891
|
+
useEffect12(() => {
|
|
1741
1892
|
windowProxy.document.title = name;
|
|
1742
1893
|
spatializedElement.updateProperties({
|
|
1743
1894
|
name
|
|
@@ -1747,11 +1898,13 @@ function useSyncDocumentTitle(windowProxy, spatializedElement, name) {
|
|
|
1747
1898
|
function SpatializedContent(props) {
|
|
1748
1899
|
const { spatializedElement, ...restProps } = props;
|
|
1749
1900
|
const spatialized2DElement = spatializedElement;
|
|
1750
|
-
const windowProxy = spatialized2DElement
|
|
1751
|
-
|
|
1901
|
+
const { windowProxy } = spatialized2DElement;
|
|
1902
|
+
useSyncHeadStyles(windowProxy, {
|
|
1903
|
+
subtree: false
|
|
1904
|
+
});
|
|
1752
1905
|
const name = restProps["data-name"] || "";
|
|
1753
1906
|
useSyncDocumentTitle(windowProxy, spatialized2DElement, name);
|
|
1754
|
-
const portalInstanceObject =
|
|
1907
|
+
const portalInstanceObject = useContext8(
|
|
1755
1908
|
PortalInstanceContext
|
|
1756
1909
|
);
|
|
1757
1910
|
const JSXPortalInstance = getJSXPortalInstance(
|
|
@@ -1776,14 +1929,14 @@ function getExtraSpatializedElementProperties(computedStyle) {
|
|
|
1776
1929
|
}
|
|
1777
1930
|
async function createSpatializedElement() {
|
|
1778
1931
|
const spatializedElement = await getSession().createSpatialized2DElement();
|
|
1779
|
-
const windowProxy = spatializedElement
|
|
1932
|
+
const { windowProxy } = spatializedElement;
|
|
1780
1933
|
setOpenWindowStyle(windowProxy);
|
|
1781
1934
|
await syncParentHeadToChild(windowProxy);
|
|
1782
1935
|
const viewport = windowProxy.document.querySelector('meta[name="viewport"]');
|
|
1783
1936
|
if (viewport) {
|
|
1784
1937
|
viewport?.setAttribute(
|
|
1785
1938
|
"content",
|
|
1786
|
-
|
|
1939
|
+
" initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
1787
1940
|
);
|
|
1788
1941
|
} else {
|
|
1789
1942
|
const meta = windowProxy.document.createElement("meta");
|
|
@@ -1813,12 +1966,10 @@ var Spatialized2DElementContainer = forwardRef5(
|
|
|
1813
1966
|
import {
|
|
1814
1967
|
forwardRef as forwardRef6,
|
|
1815
1968
|
useCallback as useCallback6,
|
|
1816
|
-
useContext as
|
|
1817
|
-
useEffect as
|
|
1969
|
+
useContext as useContext9,
|
|
1970
|
+
useEffect as useEffect13,
|
|
1818
1971
|
useMemo as useMemo3,
|
|
1819
|
-
|
|
1820
|
-
useImperativeHandle,
|
|
1821
|
-
useRef as useRef4
|
|
1972
|
+
useRef as useRef5
|
|
1822
1973
|
} from "react";
|
|
1823
1974
|
import { Fragment as Fragment2, jsx as jsx8 } from "react/jsx-runtime";
|
|
1824
1975
|
function getAbsoluteURL(url) {
|
|
@@ -1855,16 +2006,16 @@ function createLoadSuccessEvent(targetGetter) {
|
|
|
1855
2006
|
function SpatializedContent2(props) {
|
|
1856
2007
|
const { src, spatializedElement, onLoad, onError } = props;
|
|
1857
2008
|
const spatializedStatic3DElement = spatializedElement;
|
|
1858
|
-
const portalInstanceObject =
|
|
2009
|
+
const portalInstanceObject = useContext9(
|
|
1859
2010
|
PortalInstanceContext
|
|
1860
2011
|
);
|
|
1861
2012
|
const currentSrc = useMemo3(() => getAbsoluteURL(src), [src]);
|
|
1862
|
-
|
|
2013
|
+
useEffect13(() => {
|
|
1863
2014
|
if (src) {
|
|
1864
2015
|
spatializedStatic3DElement.updateProperties({ modelURL: currentSrc });
|
|
1865
2016
|
}
|
|
1866
2017
|
}, [currentSrc]);
|
|
1867
|
-
|
|
2018
|
+
useEffect13(() => {
|
|
1868
2019
|
if (onLoad) {
|
|
1869
2020
|
spatializedStatic3DElement.onLoadCallback = () => {
|
|
1870
2021
|
onLoad(
|
|
@@ -1877,7 +2028,7 @@ function SpatializedContent2(props) {
|
|
|
1877
2028
|
spatializedStatic3DElement.onLoadCallback = void 0;
|
|
1878
2029
|
}
|
|
1879
2030
|
}, [onLoad]);
|
|
1880
|
-
|
|
2031
|
+
useEffect13(() => {
|
|
1881
2032
|
if (onError) {
|
|
1882
2033
|
spatializedStatic3DElement.onLoadFailureCallback = () => {
|
|
1883
2034
|
onError(
|
|
@@ -1893,14 +2044,12 @@ function SpatializedContent2(props) {
|
|
|
1893
2044
|
return /* @__PURE__ */ jsx8(Fragment2, {});
|
|
1894
2045
|
}
|
|
1895
2046
|
function SpatializedStatic3DElementContainerBase(props, ref) {
|
|
1896
|
-
const
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
return element;
|
|
1903
|
-
}, [setElementCreated]);
|
|
2047
|
+
const promiseRef = useRef5(null);
|
|
2048
|
+
const createSpatializedElement2 = useCallback6(() => {
|
|
2049
|
+
const url = getAbsoluteURL(props.src);
|
|
2050
|
+
promiseRef.current = getSession().createSpatializedStatic3DElement(url);
|
|
2051
|
+
return promiseRef.current;
|
|
2052
|
+
}, []);
|
|
1904
2053
|
const extraRefProps = useCallback6(
|
|
1905
2054
|
(domProxy) => {
|
|
1906
2055
|
let modelTransform = new DOMMatrixReadOnly();
|
|
@@ -1909,14 +2058,10 @@ function SpatializedStatic3DElementContainerBase(props, ref) {
|
|
|
1909
2058
|
return getAbsoluteURL(props.src);
|
|
1910
2059
|
},
|
|
1911
2060
|
get ready() {
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
if (success) {
|
|
1915
|
-
return createLoadSuccessEvent(() => domProxy);
|
|
1916
|
-
}
|
|
2061
|
+
return promiseRef.current.then((spatializedElement) => spatializedElement.ready).then((success) => {
|
|
2062
|
+
if (success) return createLoadSuccessEvent(() => domProxy);
|
|
1917
2063
|
throw createLoadFailureEvent(() => domProxy);
|
|
1918
2064
|
});
|
|
1919
|
-
return promise;
|
|
1920
2065
|
},
|
|
1921
2066
|
get entityTransform() {
|
|
1922
2067
|
return modelTransform;
|
|
@@ -1924,7 +2069,7 @@ function SpatializedStatic3DElementContainerBase(props, ref) {
|
|
|
1924
2069
|
set entityTransform(value) {
|
|
1925
2070
|
modelTransform = value;
|
|
1926
2071
|
const spatializedElement = domProxy.__spatializedElement;
|
|
1927
|
-
spatializedElement
|
|
2072
|
+
spatializedElement?.updateModelTransform(modelTransform);
|
|
1928
2073
|
}
|
|
1929
2074
|
};
|
|
1930
2075
|
},
|
|
@@ -1933,7 +2078,7 @@ function SpatializedStatic3DElementContainerBase(props, ref) {
|
|
|
1933
2078
|
return /* @__PURE__ */ jsx8(
|
|
1934
2079
|
SpatializedContainer,
|
|
1935
2080
|
{
|
|
1936
|
-
ref
|
|
2081
|
+
ref,
|
|
1937
2082
|
component: "div",
|
|
1938
2083
|
createSpatializedElement: createSpatializedElement2,
|
|
1939
2084
|
spatializedContent: SpatializedContent2,
|
|
@@ -1995,10 +2140,10 @@ function initScene(name, callback, options) {
|
|
|
1995
2140
|
import { forwardRef as forwardRef9 } from "react";
|
|
1996
2141
|
|
|
1997
2142
|
// src/spatialized-container-monitor/useMonitorDomChange.tsx
|
|
1998
|
-
import { useRef as
|
|
2143
|
+
import { useRef as useRef6, useEffect as useEffect14, useMemo as useMemo4 } from "react";
|
|
1999
2144
|
function useMonitorDomChange(inRef) {
|
|
2000
|
-
const ref =
|
|
2001
|
-
|
|
2145
|
+
const ref = useRef6(null);
|
|
2146
|
+
useEffect14(() => {
|
|
2002
2147
|
const observer = new MutationObserver((mutationsList) => {
|
|
2003
2148
|
notifyDOMUpdate(mutationsList);
|
|
2004
2149
|
});
|
|
@@ -2034,9 +2179,9 @@ function useMonitorDomChange(inRef) {
|
|
|
2034
2179
|
}
|
|
2035
2180
|
|
|
2036
2181
|
// src/spatialized-container-monitor/useMonitorDocumentHeaderChange.tsx
|
|
2037
|
-
import { useEffect as
|
|
2182
|
+
import { useEffect as useEffect15 } from "react";
|
|
2038
2183
|
function useMonitorDocumentHeaderChange() {
|
|
2039
|
-
|
|
2184
|
+
useEffect15(() => {
|
|
2040
2185
|
const observer = new MutationObserver((mutationsList) => {
|
|
2041
2186
|
notifyUpdateStandInstanceLayout();
|
|
2042
2187
|
});
|
|
@@ -2096,17 +2241,70 @@ import { forwardRef as forwardRef11 } from "react";
|
|
|
2096
2241
|
import { forwardRef as forwardRef10 } from "react";
|
|
2097
2242
|
|
|
2098
2243
|
// src/reality/context/RealityContext.tsx
|
|
2099
|
-
import { createContext as
|
|
2100
|
-
var RealityContext =
|
|
2101
|
-
var useRealityContext = () =>
|
|
2244
|
+
import { createContext as createContext6, useContext as useContext10 } from "react";
|
|
2245
|
+
var RealityContext = createContext6(null);
|
|
2246
|
+
var useRealityContext = () => useContext10(RealityContext);
|
|
2102
2247
|
|
|
2103
2248
|
// src/reality/context/ParentContext.tsx
|
|
2104
|
-
import { createContext as
|
|
2105
|
-
var ParentContext =
|
|
2106
|
-
var useParentContext = () =>
|
|
2249
|
+
import { createContext as createContext7, useContext as useContext11 } from "react";
|
|
2250
|
+
var ParentContext = createContext7(null);
|
|
2251
|
+
var useParentContext = () => useContext11(ParentContext);
|
|
2252
|
+
|
|
2253
|
+
// src/reality/context/AttachmentContext.tsx
|
|
2254
|
+
import { createContext as createContext8, useContext as useContext12 } from "react";
|
|
2255
|
+
var AttachmentRegistry = class {
|
|
2256
|
+
// name → (instanceId → container)
|
|
2257
|
+
containers = /* @__PURE__ */ new Map();
|
|
2258
|
+
listeners = /* @__PURE__ */ new Map();
|
|
2259
|
+
addContainer(name, instanceId, container) {
|
|
2260
|
+
if (!this.containers.has(name)) {
|
|
2261
|
+
this.containers.set(name, /* @__PURE__ */ new Map());
|
|
2262
|
+
}
|
|
2263
|
+
this.containers.get(name).set(instanceId, container);
|
|
2264
|
+
this.notifyListeners(name);
|
|
2265
|
+
}
|
|
2266
|
+
removeContainer(name, instanceId) {
|
|
2267
|
+
this.containers.get(name)?.delete(instanceId);
|
|
2268
|
+
if (this.containers.get(name)?.size === 0) {
|
|
2269
|
+
this.containers.delete(name);
|
|
2270
|
+
}
|
|
2271
|
+
this.notifyListeners(name);
|
|
2272
|
+
}
|
|
2273
|
+
getContainers(name) {
|
|
2274
|
+
const map = this.containers.get(name);
|
|
2275
|
+
if (!map) return [];
|
|
2276
|
+
return Array.from(map, ([instanceId, container]) => ({
|
|
2277
|
+
instanceId,
|
|
2278
|
+
container
|
|
2279
|
+
}));
|
|
2280
|
+
}
|
|
2281
|
+
onContainersChange(name, cb) {
|
|
2282
|
+
const current = this.getContainers(name);
|
|
2283
|
+
if (current.length > 0) {
|
|
2284
|
+
cb(current);
|
|
2285
|
+
}
|
|
2286
|
+
const prev = this.listeners.get(name);
|
|
2287
|
+
if (prev) prev([]);
|
|
2288
|
+
this.listeners.set(name, cb);
|
|
2289
|
+
return () => {
|
|
2290
|
+
if (this.listeners.get(name) === cb) {
|
|
2291
|
+
this.listeners.delete(name);
|
|
2292
|
+
}
|
|
2293
|
+
};
|
|
2294
|
+
}
|
|
2295
|
+
notifyListeners(name) {
|
|
2296
|
+
const cs = this.getContainers(name);
|
|
2297
|
+
this.listeners.get(name)?.(cs);
|
|
2298
|
+
}
|
|
2299
|
+
destroy() {
|
|
2300
|
+
this.containers.clear();
|
|
2301
|
+
this.listeners.clear();
|
|
2302
|
+
}
|
|
2303
|
+
};
|
|
2304
|
+
var AttachmentContext = createContext8(null);
|
|
2107
2305
|
|
|
2108
2306
|
// src/reality/hooks/useEntityTransform.tsx
|
|
2109
|
-
import { useEffect as
|
|
2307
|
+
import { useEffect as useEffect16, useRef as useRef7 } from "react";
|
|
2110
2308
|
|
|
2111
2309
|
// src/reality/utils/ResourceRegistry.ts
|
|
2112
2310
|
var ResourceRegistry = class {
|
|
@@ -2187,8 +2385,8 @@ var AbortResourceManager = class {
|
|
|
2187
2385
|
|
|
2188
2386
|
// src/reality/hooks/useEntityTransform.tsx
|
|
2189
2387
|
function useEntityTransform(entity, { position, rotation, scale }) {
|
|
2190
|
-
const last =
|
|
2191
|
-
|
|
2388
|
+
const last = useRef7({});
|
|
2389
|
+
useEffect16(() => {
|
|
2192
2390
|
if (!entity) return;
|
|
2193
2391
|
const shouldUpdate = !shallowEqualVec3(last.current.position, position) || !shallowEqualRotation(last.current.rotation, rotation) || !shallowEqualVec3(last.current.scale, scale);
|
|
2194
2392
|
if (!shouldUpdate) return;
|
|
@@ -2207,7 +2405,7 @@ function useEntityTransform(entity, { position, rotation, scale }) {
|
|
|
2207
2405
|
}
|
|
2208
2406
|
|
|
2209
2407
|
// src/reality/hooks/useEntityEvent.tsx
|
|
2210
|
-
import { useEffect as
|
|
2408
|
+
import { useEffect as useEffect18, useRef as useRef9 } from "react";
|
|
2211
2409
|
|
|
2212
2410
|
// src/reality/type.ts
|
|
2213
2411
|
var eventMap = {
|
|
@@ -2218,19 +2416,17 @@ var eventMap = {
|
|
|
2218
2416
|
onSpatialDrag: "spatialdrag",
|
|
2219
2417
|
onSpatialDragEnd: "spatialdragend",
|
|
2220
2418
|
// rotate
|
|
2221
|
-
onSpatialRotateStart: "spatialrotatestart",
|
|
2222
2419
|
onSpatialRotate: "spatialrotate",
|
|
2223
2420
|
onSpatialRotateEnd: "spatialrotateend",
|
|
2224
2421
|
// magnify
|
|
2225
|
-
onSpatialMagnifyStart: "spatialmagnifystart",
|
|
2226
2422
|
onSpatialMagnify: "spatialmagnify",
|
|
2227
2423
|
onSpatialMagnifyEnd: "spatialmagnifyend"
|
|
2228
2424
|
};
|
|
2229
2425
|
|
|
2230
2426
|
// src/reality/hooks/useEntityRef.tsx
|
|
2231
|
-
import { useImperativeHandle
|
|
2427
|
+
import { useImperativeHandle } from "react";
|
|
2232
2428
|
var useEntityRef = (ref, instance) => {
|
|
2233
|
-
|
|
2429
|
+
useImperativeHandle(ref, () => instance);
|
|
2234
2430
|
};
|
|
2235
2431
|
var EntityRef = class {
|
|
2236
2432
|
_entity;
|
|
@@ -2297,7 +2493,8 @@ var EntityRef = class {
|
|
|
2297
2493
|
}
|
|
2298
2494
|
};
|
|
2299
2495
|
|
|
2300
|
-
// src/reality/hooks/
|
|
2496
|
+
// src/reality/hooks/useRealityEvents.tsx
|
|
2497
|
+
import { useEffect as useEffect19, useRef as useRef10 } from "react";
|
|
2301
2498
|
function createEventProxy2(ev, instance) {
|
|
2302
2499
|
return new Proxy(ev, {
|
|
2303
2500
|
get(target, prop) {
|
|
@@ -2344,44 +2541,99 @@ function createEventProxy2(ev, instance) {
|
|
|
2344
2541
|
}
|
|
2345
2542
|
return void 0;
|
|
2346
2543
|
}
|
|
2544
|
+
if (prop === "translationX") {
|
|
2545
|
+
const type = target.type;
|
|
2546
|
+
if (type === "spatialdrag") {
|
|
2547
|
+
return target.detail?.translation3D?.x ?? 0;
|
|
2548
|
+
}
|
|
2549
|
+
return void 0;
|
|
2550
|
+
}
|
|
2551
|
+
if (prop === "translationY") {
|
|
2552
|
+
const type = target.type;
|
|
2553
|
+
if (type === "spatialdrag") {
|
|
2554
|
+
return target.detail?.translation3D?.y ?? 0;
|
|
2555
|
+
}
|
|
2556
|
+
return void 0;
|
|
2557
|
+
}
|
|
2558
|
+
if (prop === "translationZ") {
|
|
2559
|
+
const type = target.type;
|
|
2560
|
+
if (type === "spatialdrag") {
|
|
2561
|
+
return target.detail?.translation3D?.z ?? 0;
|
|
2562
|
+
}
|
|
2563
|
+
return void 0;
|
|
2564
|
+
}
|
|
2565
|
+
if (prop === "quaternion") {
|
|
2566
|
+
const type = target.type;
|
|
2567
|
+
if (type === "spatialrotate") {
|
|
2568
|
+
return target.detail?.quaternion ?? {
|
|
2569
|
+
x: 0,
|
|
2570
|
+
y: 0,
|
|
2571
|
+
z: 0,
|
|
2572
|
+
w: 1
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
return void 0;
|
|
2576
|
+
}
|
|
2577
|
+
if (prop === "magnification") {
|
|
2578
|
+
const type = target.type;
|
|
2579
|
+
if (type === "spatialmagnify") {
|
|
2580
|
+
return target.detail?.magnification ?? 1;
|
|
2581
|
+
}
|
|
2582
|
+
return void 0;
|
|
2583
|
+
}
|
|
2584
|
+
if (prop === "clientX") {
|
|
2585
|
+
const type = target.type;
|
|
2586
|
+
if (type === "spatialtap" || type === "spatialdragstart") {
|
|
2587
|
+
return target.detail?.globalLocation3D?.x ?? 0;
|
|
2588
|
+
}
|
|
2589
|
+
return void 0;
|
|
2590
|
+
}
|
|
2591
|
+
if (prop === "clientY") {
|
|
2592
|
+
const type = target.type;
|
|
2593
|
+
if (type === "spatialtap" || type === "spatialdragstart") {
|
|
2594
|
+
return target.detail?.globalLocation3D?.y ?? 0;
|
|
2595
|
+
}
|
|
2596
|
+
return void 0;
|
|
2597
|
+
}
|
|
2598
|
+
if (prop === "clientZ") {
|
|
2599
|
+
const type = target.type;
|
|
2600
|
+
if (type === "spatialtap" || type === "spatialdragstart") {
|
|
2601
|
+
return target.detail?.globalLocation3D?.z ?? 0;
|
|
2602
|
+
}
|
|
2603
|
+
return void 0;
|
|
2604
|
+
}
|
|
2347
2605
|
const val = target[prop];
|
|
2348
2606
|
return typeof val === "function" ? val.bind(target) : val;
|
|
2349
2607
|
}
|
|
2350
2608
|
});
|
|
2351
2609
|
}
|
|
2352
|
-
var
|
|
2353
|
-
const eventsSetRef =
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
if (!entity) return;
|
|
2610
|
+
var useRealityEvents = ({ instance, ...handlers }) => {
|
|
2611
|
+
const eventsSetRef = useRef10(/* @__PURE__ */ new Set());
|
|
2612
|
+
useEffect19(() => {
|
|
2613
|
+
if (!instance) return;
|
|
2357
2614
|
Object.entries(eventMap).forEach(([reactKey, spatialEvent]) => {
|
|
2358
2615
|
const handlerFn = handlers[reactKey];
|
|
2359
2616
|
if (!handlerFn) return;
|
|
2360
2617
|
const wrapped = (ev) => handlerFn(createEventProxy2(ev, instance));
|
|
2361
|
-
|
|
2362
|
-
eventsSetRef.current.add(
|
|
2618
|
+
instance.addEvent(spatialEvent, wrapped);
|
|
2619
|
+
eventsSetRef.current.add(spatialEvent);
|
|
2363
2620
|
});
|
|
2364
2621
|
return () => {
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
return () => {
|
|
2371
|
-
for (let x of eventsSetRef.current) {
|
|
2372
|
-
entity.removeEvent(x);
|
|
2622
|
+
if (instance) {
|
|
2623
|
+
for (let x of eventsSetRef.current) {
|
|
2624
|
+
instance.removeEvent(x);
|
|
2625
|
+
}
|
|
2626
|
+
eventsSetRef.current.clear();
|
|
2373
2627
|
}
|
|
2374
|
-
eventsSetRef.current.clear();
|
|
2375
2628
|
};
|
|
2376
|
-
}, [instance.
|
|
2377
|
-
return null;
|
|
2629
|
+
}, [instance, ...Object.values(handlers)]);
|
|
2378
2630
|
};
|
|
2379
2631
|
|
|
2380
2632
|
// src/reality/hooks/useEntityId.tsx
|
|
2381
|
-
import { useEffect as
|
|
2633
|
+
import { useEffect as useEffect20 } from "react";
|
|
2382
2634
|
var useEntityId = ({ id, entity }) => {
|
|
2383
2635
|
const ctx = useRealityContext();
|
|
2384
|
-
|
|
2636
|
+
useEffect20(() => {
|
|
2385
2637
|
if (!id || !entity || !ctx) return;
|
|
2386
2638
|
ctx.resourceRegistry.add(id, Promise.resolve(entity));
|
|
2387
2639
|
return () => {
|
|
@@ -2392,31 +2644,21 @@ var useEntityId = ({ id, entity }) => {
|
|
|
2392
2644
|
};
|
|
2393
2645
|
|
|
2394
2646
|
// src/reality/hooks/useEntity.tsx
|
|
2395
|
-
import { useEffect as
|
|
2647
|
+
import { useEffect as useEffect21, useRef as useRef11 } from "react";
|
|
2396
2648
|
var useEntity = ({
|
|
2397
2649
|
ref,
|
|
2398
2650
|
id,
|
|
2399
2651
|
position,
|
|
2400
2652
|
rotation,
|
|
2401
2653
|
scale,
|
|
2402
|
-
|
|
2403
|
-
onSpatialDragStart,
|
|
2404
|
-
onSpatialDrag,
|
|
2405
|
-
onSpatialDragEnd,
|
|
2406
|
-
// onSpatialRotateStart,
|
|
2407
|
-
onSpatialRotate,
|
|
2408
|
-
onSpatialRotateEnd,
|
|
2409
|
-
// onSpatialMagnifyStart,
|
|
2410
|
-
onSpatialMagnify,
|
|
2411
|
-
onSpatialMagnifyEnd,
|
|
2412
|
-
// TODO: add other event handlers
|
|
2654
|
+
enableInput,
|
|
2413
2655
|
createEntity
|
|
2414
2656
|
}) => {
|
|
2415
2657
|
const ctx = useRealityContext();
|
|
2416
2658
|
const parent = useParentContext();
|
|
2417
|
-
const instanceRef =
|
|
2659
|
+
const instanceRef = useRef11(new EntityRef(null, ctx));
|
|
2418
2660
|
const forceUpdate = useForceUpdate2();
|
|
2419
|
-
|
|
2661
|
+
useEffect21(() => {
|
|
2420
2662
|
if (!ctx) return;
|
|
2421
2663
|
const controller = new AbortController();
|
|
2422
2664
|
const init = async () => {
|
|
@@ -2449,26 +2691,20 @@ var useEntity = ({
|
|
|
2449
2691
|
useEntityId({ id, entity: instanceRef.current.entity });
|
|
2450
2692
|
useEntityTransform(instanceRef.current.entity, { position, rotation, scale });
|
|
2451
2693
|
useEntityRef(ref, instanceRef.current);
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
onSpatialRotate,
|
|
2460
|
-
onSpatialRotateEnd,
|
|
2461
|
-
// onSpatialMagnifyStart,
|
|
2462
|
-
onSpatialMagnify,
|
|
2463
|
-
onSpatialMagnifyEnd
|
|
2464
|
-
});
|
|
2694
|
+
useEffect21(() => {
|
|
2695
|
+
const ent = instanceRef.current.entity;
|
|
2696
|
+
if (!ent) return;
|
|
2697
|
+
if (enableInput !== void 0) {
|
|
2698
|
+
ent.enableInput = !!enableInput;
|
|
2699
|
+
}
|
|
2700
|
+
}, [instanceRef.current.entity, enableInput]);
|
|
2465
2701
|
return instanceRef.current.entity;
|
|
2466
2702
|
};
|
|
2467
2703
|
|
|
2468
2704
|
// src/reality/hooks/useForceUpdate.tsx
|
|
2469
|
-
import { useCallback as useCallback7, useState as
|
|
2705
|
+
import { useCallback as useCallback7, useState as useState7 } from "react";
|
|
2470
2706
|
var useForceUpdate2 = () => {
|
|
2471
|
-
const [, setTick] =
|
|
2707
|
+
const [, setTick] = useState7(0);
|
|
2472
2708
|
return useCallback7(() => setTick((tick) => tick + 1), []);
|
|
2473
2709
|
};
|
|
2474
2710
|
|
|
@@ -2573,11 +2809,14 @@ var BoxEntity = forwardRef13(
|
|
|
2573
2809
|
);
|
|
2574
2810
|
|
|
2575
2811
|
// src/reality/components/UnlitMaterial.tsx
|
|
2576
|
-
import { useEffect as
|
|
2577
|
-
var UnlitMaterial = ({
|
|
2812
|
+
import { useEffect as useEffect22, useRef as useRef12 } from "react";
|
|
2813
|
+
var UnlitMaterial = ({
|
|
2814
|
+
children,
|
|
2815
|
+
...options
|
|
2816
|
+
}) => {
|
|
2578
2817
|
const ctx = useRealityContext();
|
|
2579
|
-
const materialRef =
|
|
2580
|
-
|
|
2818
|
+
const materialRef = useRef12();
|
|
2819
|
+
useEffect22(() => {
|
|
2581
2820
|
if (!ctx) return;
|
|
2582
2821
|
const { session, reality, resourceRegistry } = ctx;
|
|
2583
2822
|
const init = async () => {
|
|
@@ -2693,7 +2932,7 @@ var SceneGraph = ({ children }) => {
|
|
|
2693
2932
|
};
|
|
2694
2933
|
|
|
2695
2934
|
// src/reality/components/ModelAsset.tsx
|
|
2696
|
-
import { useEffect as
|
|
2935
|
+
import { useEffect as useEffect23, useRef as useRef13 } from "react";
|
|
2697
2936
|
var resolveAssetUrl = (url) => {
|
|
2698
2937
|
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
2699
2938
|
return url;
|
|
@@ -2702,8 +2941,8 @@ var resolveAssetUrl = (url) => {
|
|
|
2702
2941
|
};
|
|
2703
2942
|
var ModelAsset = ({ children, ...options }) => {
|
|
2704
2943
|
const ctx = useRealityContext();
|
|
2705
|
-
const materialRef =
|
|
2706
|
-
|
|
2944
|
+
const materialRef = useRef13();
|
|
2945
|
+
useEffect23(() => {
|
|
2707
2946
|
const controller = new AbortController();
|
|
2708
2947
|
if (!ctx) return;
|
|
2709
2948
|
const { session, reality, resourceRegistry } = ctx;
|
|
@@ -2770,13 +3009,20 @@ var ModelEntity = forwardRef18(
|
|
|
2770
3009
|
import {
|
|
2771
3010
|
forwardRef as forwardRef19,
|
|
2772
3011
|
useCallback as useCallback8,
|
|
2773
|
-
useEffect as
|
|
2774
|
-
useRef as
|
|
2775
|
-
useState as
|
|
3012
|
+
useEffect as useEffect24,
|
|
3013
|
+
useRef as useRef14,
|
|
3014
|
+
useState as useState8
|
|
2776
3015
|
} from "react";
|
|
2777
3016
|
import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2778
3017
|
var Reality = forwardRef19(
|
|
2779
3018
|
function RealityBase({ children, ...inProps }, ref) {
|
|
3019
|
+
const insideAttachment = useInsideAttachment();
|
|
3020
|
+
if (insideAttachment) {
|
|
3021
|
+
console.warn(
|
|
3022
|
+
"[WebSpatial] Reality cannot be used inside AttachmentAsset."
|
|
3023
|
+
);
|
|
3024
|
+
return null;
|
|
3025
|
+
}
|
|
2780
3026
|
const {
|
|
2781
3027
|
onSpatialTap,
|
|
2782
3028
|
onSpatialDragStart,
|
|
@@ -2788,16 +3034,17 @@ var Reality = forwardRef19(
|
|
|
2788
3034
|
onSpatialMagnifyEnd,
|
|
2789
3035
|
...props
|
|
2790
3036
|
} = inProps;
|
|
2791
|
-
const ctxRef =
|
|
2792
|
-
const creationId =
|
|
2793
|
-
const [isReady, setIsReady] =
|
|
3037
|
+
const ctxRef = useRef14(null);
|
|
3038
|
+
const creationId = useRef14(0);
|
|
3039
|
+
const [isReady, setIsReady] = useState8(false);
|
|
2794
3040
|
const cleanupReality = useCallback8(() => {
|
|
3041
|
+
ctxRef.current?.attachmentRegistry.destroy();
|
|
2795
3042
|
ctxRef.current?.resourceRegistry.destroy();
|
|
2796
3043
|
ctxRef.current?.reality.destroy();
|
|
2797
3044
|
ctxRef.current = null;
|
|
2798
3045
|
setIsReady(false);
|
|
2799
3046
|
}, []);
|
|
2800
|
-
|
|
3047
|
+
useEffect24(() => {
|
|
2801
3048
|
return () => {
|
|
2802
3049
|
creationId.current++;
|
|
2803
3050
|
cleanupReality();
|
|
@@ -2806,15 +3053,18 @@ var Reality = forwardRef19(
|
|
|
2806
3053
|
const createReality = useCallback8(async () => {
|
|
2807
3054
|
const id = ++creationId.current;
|
|
2808
3055
|
const resourceRegistry = new ResourceRegistry();
|
|
3056
|
+
const attachmentRegistry = new AttachmentRegistry();
|
|
2809
3057
|
const session = await getSession();
|
|
2810
3058
|
if (!session) {
|
|
2811
3059
|
resourceRegistry.destroy();
|
|
3060
|
+
attachmentRegistry.destroy();
|
|
2812
3061
|
return null;
|
|
2813
3062
|
}
|
|
2814
3063
|
const reality = await session.createSpatializedDynamic3DElement();
|
|
2815
3064
|
const isCancelled = () => id !== creationId.current;
|
|
2816
3065
|
if (isCancelled()) {
|
|
2817
3066
|
resourceRegistry.destroy();
|
|
3067
|
+
attachmentRegistry.destroy();
|
|
2818
3068
|
reality.destroy();
|
|
2819
3069
|
return null;
|
|
2820
3070
|
}
|
|
@@ -2822,21 +3072,39 @@ var Reality = forwardRef19(
|
|
|
2822
3072
|
const result = await session.getSpatialScene().addSpatializedElement(reality);
|
|
2823
3073
|
if (!result.success || isCancelled()) {
|
|
2824
3074
|
resourceRegistry.destroy();
|
|
3075
|
+
attachmentRegistry.destroy();
|
|
2825
3076
|
reality.destroy();
|
|
2826
3077
|
return null;
|
|
2827
3078
|
}
|
|
2828
3079
|
cleanupReality();
|
|
2829
|
-
ctxRef.current = {
|
|
3080
|
+
ctxRef.current = {
|
|
3081
|
+
session,
|
|
3082
|
+
reality,
|
|
3083
|
+
resourceRegistry,
|
|
3084
|
+
attachmentRegistry
|
|
3085
|
+
};
|
|
2830
3086
|
setIsReady(true);
|
|
2831
3087
|
return reality;
|
|
2832
3088
|
} catch (err) {
|
|
2833
3089
|
console.error("[createReality] failed", err);
|
|
2834
3090
|
resourceRegistry.destroy();
|
|
3091
|
+
attachmentRegistry.destroy();
|
|
2835
3092
|
reality.destroy();
|
|
2836
3093
|
return null;
|
|
2837
3094
|
}
|
|
2838
3095
|
}, [cleanupReality]);
|
|
2839
3096
|
const content = useCallback8(() => /* @__PURE__ */ jsx22(Fragment3, {}), []);
|
|
3097
|
+
useRealityEvents({
|
|
3098
|
+
instance: ctxRef.current?.reality ?? null,
|
|
3099
|
+
onSpatialTap,
|
|
3100
|
+
onSpatialDragStart,
|
|
3101
|
+
onSpatialDrag,
|
|
3102
|
+
onSpatialDragEnd,
|
|
3103
|
+
onSpatialRotate,
|
|
3104
|
+
onSpatialRotateEnd,
|
|
3105
|
+
onSpatialMagnify,
|
|
3106
|
+
onSpatialMagnifyEnd
|
|
3107
|
+
});
|
|
2840
3108
|
return /* @__PURE__ */ jsxs3(RealityContext.Provider, { value: ctxRef.current, children: [
|
|
2841
3109
|
/* @__PURE__ */ jsx22(
|
|
2842
3110
|
SpatializedContainer,
|
|
@@ -2853,14 +3121,146 @@ var Reality = forwardRef19(
|
|
|
2853
3121
|
}
|
|
2854
3122
|
);
|
|
2855
3123
|
|
|
3124
|
+
// src/reality/components/AttachmentAsset.tsx
|
|
3125
|
+
import { useEffect as useEffect25, useState as useState9 } from "react";
|
|
3126
|
+
import { createPortal as createPortal3 } from "react-dom";
|
|
3127
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3128
|
+
var AttachmentAsset = ({
|
|
3129
|
+
name,
|
|
3130
|
+
children
|
|
3131
|
+
}) => {
|
|
3132
|
+
const ctx = useRealityContext();
|
|
3133
|
+
const [containers, setContainers] = useState9([]);
|
|
3134
|
+
useEffect25(() => {
|
|
3135
|
+
if (!ctx) return;
|
|
3136
|
+
return ctx.attachmentRegistry.onContainersChange(name, setContainers);
|
|
3137
|
+
}, [ctx, name]);
|
|
3138
|
+
if (!containers.length) return null;
|
|
3139
|
+
return /* @__PURE__ */ jsx23(InsideAttachmentContext.Provider, { value: true, children: containers.map(
|
|
3140
|
+
({ instanceId, container }) => createPortal3(children, container, instanceId)
|
|
3141
|
+
) });
|
|
3142
|
+
};
|
|
3143
|
+
|
|
3144
|
+
// src/reality/components/AttachmentEntity.tsx
|
|
3145
|
+
import { useEffect as useEffect26, useRef as useRef15, useState as useState10 } from "react";
|
|
3146
|
+
var instanceCounter = 0;
|
|
3147
|
+
var AttachmentEntity = ({
|
|
3148
|
+
attachment: attachmentName,
|
|
3149
|
+
position,
|
|
3150
|
+
size
|
|
3151
|
+
}) => {
|
|
3152
|
+
const ctx = useRealityContext();
|
|
3153
|
+
const parent = useParentContext();
|
|
3154
|
+
const attachmentRef = useRef15(null);
|
|
3155
|
+
const parentIdRef = useRef15(null);
|
|
3156
|
+
const instanceIdRef = useRef15(`att_${++instanceCounter}`);
|
|
3157
|
+
const attachmentNameRef = useRef15(attachmentName);
|
|
3158
|
+
const [childWindow, setChildWindow] = useState10(null);
|
|
3159
|
+
useEffect26(() => {
|
|
3160
|
+
if (!ctx || !parent) return;
|
|
3161
|
+
if (attachmentRef.current) return;
|
|
3162
|
+
const parentId = parent.id;
|
|
3163
|
+
parentIdRef.current = parentId;
|
|
3164
|
+
let cancelled = false;
|
|
3165
|
+
const init = async () => {
|
|
3166
|
+
try {
|
|
3167
|
+
const att = await ctx.session.createAttachmentEntity({
|
|
3168
|
+
parentEntityId: parentId,
|
|
3169
|
+
position: position ?? [0, 0, 0],
|
|
3170
|
+
size,
|
|
3171
|
+
ownerViewId: ctx.reality.id
|
|
3172
|
+
});
|
|
3173
|
+
if (cancelled) {
|
|
3174
|
+
att.destroy();
|
|
3175
|
+
return;
|
|
3176
|
+
}
|
|
3177
|
+
const windowProxy = att.getWindowProxy();
|
|
3178
|
+
setOpenWindowStyle(windowProxy);
|
|
3179
|
+
windowProxy.document.body.style.display = "block";
|
|
3180
|
+
windowProxy.document.body.style.minWidth = "100%";
|
|
3181
|
+
windowProxy.document.body.style.maxWidth = "100%";
|
|
3182
|
+
windowProxy.document.body.style.minHeight = "100%";
|
|
3183
|
+
const viewport = windowProxy.document.querySelector(
|
|
3184
|
+
'meta[name="viewport"]'
|
|
3185
|
+
);
|
|
3186
|
+
if (!viewport) {
|
|
3187
|
+
const meta = windowProxy.document.createElement("meta");
|
|
3188
|
+
meta.name = "viewport";
|
|
3189
|
+
meta.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no";
|
|
3190
|
+
windowProxy.document.head.appendChild(meta);
|
|
3191
|
+
}
|
|
3192
|
+
const base = windowProxy.document.createElement("base");
|
|
3193
|
+
base.href = document.baseURI;
|
|
3194
|
+
windowProxy.document.head.appendChild(base);
|
|
3195
|
+
attachmentRef.current = att;
|
|
3196
|
+
setChildWindow(windowProxy);
|
|
3197
|
+
ctx.attachmentRegistry.addContainer(
|
|
3198
|
+
attachmentNameRef.current,
|
|
3199
|
+
instanceIdRef.current,
|
|
3200
|
+
att.getContainer()
|
|
3201
|
+
);
|
|
3202
|
+
} catch (error) {
|
|
3203
|
+
console.error("[AttachmentEntity] init error:", error);
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3206
|
+
init();
|
|
3207
|
+
return () => {
|
|
3208
|
+
cancelled = true;
|
|
3209
|
+
const att = attachmentRef.current;
|
|
3210
|
+
if (att) {
|
|
3211
|
+
ctx.attachmentRegistry.removeContainer(
|
|
3212
|
+
attachmentNameRef.current,
|
|
3213
|
+
instanceIdRef.current
|
|
3214
|
+
);
|
|
3215
|
+
att.destroy();
|
|
3216
|
+
attachmentRef.current = null;
|
|
3217
|
+
setChildWindow(null);
|
|
3218
|
+
}
|
|
3219
|
+
};
|
|
3220
|
+
}, [ctx, parent]);
|
|
3221
|
+
useEffect26(() => {
|
|
3222
|
+
if (!ctx) return;
|
|
3223
|
+
const att = attachmentRef.current;
|
|
3224
|
+
const prevName = attachmentNameRef.current;
|
|
3225
|
+
if (att && prevName !== attachmentName) {
|
|
3226
|
+
ctx.attachmentRegistry.removeContainer(prevName, instanceIdRef.current);
|
|
3227
|
+
ctx.attachmentRegistry.addContainer(
|
|
3228
|
+
attachmentName,
|
|
3229
|
+
instanceIdRef.current,
|
|
3230
|
+
att.getContainer()
|
|
3231
|
+
);
|
|
3232
|
+
attachmentNameRef.current = attachmentName;
|
|
3233
|
+
} else {
|
|
3234
|
+
attachmentNameRef.current = attachmentName;
|
|
3235
|
+
}
|
|
3236
|
+
}, [ctx, attachmentName]);
|
|
3237
|
+
useSyncHeadStyles(childWindow, { subtree: false });
|
|
3238
|
+
useEffect26(() => {
|
|
3239
|
+
if (!attachmentRef.current) return;
|
|
3240
|
+
attachmentRef.current.update({ position, size });
|
|
3241
|
+
}, [position?.[0], position?.[1], position?.[2], size?.width, size?.height]);
|
|
3242
|
+
return null;
|
|
3243
|
+
};
|
|
3244
|
+
|
|
3245
|
+
// src/reality/components/Material.tsx
|
|
3246
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3247
|
+
var Material = (props) => {
|
|
3248
|
+
if (props.type === "unlit") {
|
|
3249
|
+
const { type, ...rest } = props;
|
|
3250
|
+
return /* @__PURE__ */ jsx24(UnlitMaterial, { ...rest });
|
|
3251
|
+
}
|
|
3252
|
+
return null;
|
|
3253
|
+
};
|
|
3254
|
+
|
|
2856
3255
|
// src/Model.tsx
|
|
2857
3256
|
import { forwardRef as forwardRef20 } from "react";
|
|
2858
3257
|
import { Spatial as Spatial2 } from "@webspatial/core-sdk";
|
|
2859
|
-
import { jsx as
|
|
3258
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2860
3259
|
var spatial2 = new Spatial2();
|
|
2861
3260
|
function ModelBase(props, ref) {
|
|
3261
|
+
const insideAttachment = useInsideAttachment();
|
|
2862
3262
|
const { "enable-xr": enableXR, ...restProps } = props;
|
|
2863
|
-
if (!enableXR || !spatial2.runInSpatialWeb()) {
|
|
3263
|
+
if (!enableXR || !spatial2.runInSpatialWeb() || insideAttachment) {
|
|
2864
3264
|
const {
|
|
2865
3265
|
onSpatialTap,
|
|
2866
3266
|
onSpatialDragStart,
|
|
@@ -2870,28 +3270,126 @@ function ModelBase(props, ref) {
|
|
|
2870
3270
|
onSpatialRotateEnd,
|
|
2871
3271
|
onSpatialMagnify,
|
|
2872
3272
|
onSpatialMagnifyEnd,
|
|
3273
|
+
spatialEventOptions: _spatialEventOptions,
|
|
2873
3274
|
...modelProps
|
|
2874
3275
|
} = restProps;
|
|
2875
|
-
return /* @__PURE__ */
|
|
3276
|
+
return /* @__PURE__ */ jsx25("model", { ref, ...modelProps });
|
|
2876
3277
|
}
|
|
2877
|
-
return /* @__PURE__ */
|
|
3278
|
+
return /* @__PURE__ */ jsx25(SpatializedStatic3DElementContainer, { ref, ...restProps });
|
|
2878
3279
|
}
|
|
2879
3280
|
var Model = withSSRSupported(forwardRef20(ModelBase));
|
|
2880
3281
|
Model.displayName = "Model";
|
|
2881
3282
|
|
|
3283
|
+
// src/useMetrics.tsx
|
|
3284
|
+
import { useSyncExternalStore } from "react";
|
|
3285
|
+
import { PhysicalMetrics } from "@webspatial/core-sdk";
|
|
3286
|
+
function useMetrics() {
|
|
3287
|
+
useSyncExternalStore(PhysicalMetrics.subscribe, PhysicalMetrics.getValue);
|
|
3288
|
+
const { pointToPhysical, physicalToPoint } = PhysicalMetrics;
|
|
3289
|
+
return { pointToPhysical, physicalToPoint };
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3292
|
+
// src/jsx/jsx-shared.ts
|
|
3293
|
+
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
|
|
3294
|
+
import reactJSXRuntime from "react/jsx-runtime";
|
|
3295
|
+
import { createElement as reactCreateElement } from "react";
|
|
3296
|
+
var attributeFlag = "enable-xr";
|
|
3297
|
+
var styleFlag = "enableXr";
|
|
3298
|
+
var classFlag = "__enableXr__";
|
|
3299
|
+
var xrMonitorFlag = "enable-xr-monitor";
|
|
3300
|
+
function replaceToSpatialPrimitiveType(type, props) {
|
|
3301
|
+
if (type === Model) {
|
|
3302
|
+
return type;
|
|
3303
|
+
}
|
|
3304
|
+
const propsObject = props;
|
|
3305
|
+
if (attributeFlag in propsObject) {
|
|
3306
|
+
delete propsObject[attributeFlag];
|
|
3307
|
+
return withSpatialized2DElementContainer(type);
|
|
3308
|
+
}
|
|
3309
|
+
if (xrMonitorFlag in propsObject) {
|
|
3310
|
+
delete propsObject[xrMonitorFlag];
|
|
3311
|
+
return withSpatialMonitor(type);
|
|
3312
|
+
}
|
|
3313
|
+
if (propsObject && propsObject.style && styleFlag in propsObject.style) {
|
|
3314
|
+
delete propsObject.style[styleFlag];
|
|
3315
|
+
return withSpatialized2DElementContainer(type);
|
|
3316
|
+
}
|
|
3317
|
+
if (propsObject && typeof propsObject.className === "string") {
|
|
3318
|
+
const originalClassNames = propsObject.className.split(" ");
|
|
3319
|
+
const idx = originalClassNames.indexOf(classFlag);
|
|
3320
|
+
if (idx !== -1) {
|
|
3321
|
+
originalClassNames.splice(idx, 1);
|
|
3322
|
+
propsObject.className = originalClassNames.join(" ");
|
|
3323
|
+
return withSpatialized2DElementContainer(type);
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
return type;
|
|
3327
|
+
}
|
|
3328
|
+
function createElement(...args) {
|
|
3329
|
+
const [type, props, ...rest] = args;
|
|
3330
|
+
const newType = replaceToSpatialPrimitiveType(type, props);
|
|
3331
|
+
return reactCreateElement(newType, props, ...rest);
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
// src/utils/convertCoordinate.ts
|
|
3335
|
+
function resolveSpatialObjectId(target) {
|
|
3336
|
+
if (typeof window !== "undefined" && target === window) {
|
|
3337
|
+
const scene = getSession()?.getSpatialScene();
|
|
3338
|
+
return scene?.id ?? "";
|
|
3339
|
+
}
|
|
3340
|
+
const maybeEntity = target;
|
|
3341
|
+
if (maybeEntity && typeof maybeEntity === "object" && "entity" in maybeEntity) {
|
|
3342
|
+
return maybeEntity.entity?.id ?? null;
|
|
3343
|
+
}
|
|
3344
|
+
const dom = target?.__raw ?? target;
|
|
3345
|
+
if (dom && typeof dom === "object") {
|
|
3346
|
+
const spatializedElement = dom.__spatializedElement ?? dom.__innerSpatializedElement?.();
|
|
3347
|
+
if (spatializedElement && spatializedElement.id) {
|
|
3348
|
+
return spatializedElement.id;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
return null;
|
|
3352
|
+
}
|
|
3353
|
+
async function convertCoordinate(position, { from, to }) {
|
|
3354
|
+
try {
|
|
3355
|
+
const fromId = resolveSpatialObjectId(from);
|
|
3356
|
+
const toId = resolveSpatialObjectId(to);
|
|
3357
|
+
if (fromId === null || toId === null) {
|
|
3358
|
+
console.warn(
|
|
3359
|
+
"convertCoordinate error: from or to is not a valid coordinate convertible"
|
|
3360
|
+
);
|
|
3361
|
+
return position;
|
|
3362
|
+
}
|
|
3363
|
+
const spatialScene = getSession()?.getSpatialScene();
|
|
3364
|
+
if (!spatialScene) return position;
|
|
3365
|
+
const ret = await spatialScene.convertCoordinate(position, fromId, toId);
|
|
3366
|
+
return ret ?? position;
|
|
3367
|
+
} catch (error) {
|
|
3368
|
+
console.warn("convertCoordinate error:", error);
|
|
3369
|
+
return position;
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
|
|
2882
3373
|
// src/index.ts
|
|
2883
|
-
var version = "1.
|
|
3374
|
+
var version = "1.4.0";
|
|
2884
3375
|
if (typeof window !== "undefined") {
|
|
2885
3376
|
initPolyfill();
|
|
2886
3377
|
}
|
|
2887
3378
|
export {
|
|
3379
|
+
AttachmentAsset,
|
|
3380
|
+
AttachmentEntity,
|
|
3381
|
+
BoxEntity as Box,
|
|
2888
3382
|
BoxEntity,
|
|
3383
|
+
ConeEntity as Cone,
|
|
2889
3384
|
ConeEntity,
|
|
3385
|
+
CylinderEntity as Cylinder,
|
|
2890
3386
|
CylinderEntity,
|
|
2891
3387
|
Entity,
|
|
3388
|
+
Material,
|
|
2892
3389
|
Model,
|
|
2893
3390
|
ModelAsset,
|
|
2894
3391
|
ModelEntity,
|
|
3392
|
+
PlaneEntity as Plane,
|
|
2895
3393
|
PlaneEntity,
|
|
2896
3394
|
Reality,
|
|
2897
3395
|
SSRProvider,
|
|
@@ -2900,14 +3398,17 @@ export {
|
|
|
2900
3398
|
Spatialized2DElementContainer,
|
|
2901
3399
|
SpatializedContainer,
|
|
2902
3400
|
SpatializedStatic3DElementContainer,
|
|
3401
|
+
SphereEntity as Sphere,
|
|
2903
3402
|
SphereEntity,
|
|
2904
3403
|
UnlitMaterial,
|
|
3404
|
+
SceneGraph as World,
|
|
3405
|
+
convertCoordinate,
|
|
3406
|
+
createElement,
|
|
2905
3407
|
enableDebugTool,
|
|
2906
3408
|
eventMap,
|
|
2907
3409
|
initPolyfill,
|
|
2908
3410
|
initScene,
|
|
2909
|
-
|
|
2910
|
-
toSceneSpatial,
|
|
3411
|
+
useMetrics,
|
|
2911
3412
|
version,
|
|
2912
3413
|
withSpatialMonitor,
|
|
2913
3414
|
withSpatialized2DElementContainer
|