@neurodyn/react-model-viewer 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7 -3
- package/dist/index.js +129 -44
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -21,15 +21,15 @@ declare type DialogProps = React_3.ComponentProps<typeof DialogPrimitive.Root>
|
|
|
21
21
|
*/
|
|
22
22
|
export declare type LaunchArOverride = (target: ArLaunchTarget) => boolean | Promise<boolean>;
|
|
23
23
|
|
|
24
|
-
export declare function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, launchAr, sizeType, layout, background, viewerSurface, className, ...props }: ModelViewerProps & React_2.ComponentProps<'div'>): JSX.Element;
|
|
24
|
+
export declare function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, launchAr, sizeType, dimensionAxes, layout, background, viewerSurface, className, ...props }: ModelViewerProps & React_2.ComponentProps<'div'>): JSX.Element;
|
|
25
25
|
|
|
26
26
|
export declare type ModelViewerArExperience = 'advanced' | 'standard';
|
|
27
27
|
|
|
28
28
|
declare type ModelViewerBackground = 'default' | 'transparent';
|
|
29
29
|
|
|
30
|
-
export declare function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, initialWidgetSessionToken, handoffUrl, hid, sizeType, ...props }: ModelViewerDialogProps): JSX.Element;
|
|
30
|
+
export declare function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, initialWidgetSessionToken, handoffUrl, hid, sizeType, dimensionAxes, ...props }: ModelViewerDialogProps): JSX.Element;
|
|
31
31
|
|
|
32
|
-
declare interface ModelViewerDialogProps extends Pick<ModelViewerRootProps, 'apiBaseUrl' | 'apiKey' | 'handoffUrl' | 'hid' | 'initialWidgetSessionToken' | 'legacyApiBaseUrl' | 'sizeType' | 'tinuuid'>, Omit<DialogProps, 'children'> {
|
|
32
|
+
declare interface ModelViewerDialogProps extends Pick<ModelViewerRootProps, 'apiBaseUrl' | 'apiKey' | 'dimensionAxes' | 'handoffUrl' | 'hid' | 'initialWidgetSessionToken' | 'legacyApiBaseUrl' | 'sizeType' | 'tinuuid'>, Omit<DialogProps, 'children'> {
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
declare type ModelViewerLayout = 'default' | 'model';
|
|
@@ -62,6 +62,8 @@ declare interface ModelViewerRootProps {
|
|
|
62
62
|
launchAr?: LaunchArOverride;
|
|
63
63
|
/** Display unit for model dimensions. */
|
|
64
64
|
sizeType?: SizeType;
|
|
65
|
+
/** Which axes' measurements the "Show dimensions" overlay draws. Defaults to all three. */
|
|
66
|
+
dimensionAxes?: SizeAxis[];
|
|
65
67
|
/** Controls which viewer UI elements are shown. */
|
|
66
68
|
layout?: ModelViewerLayout;
|
|
67
69
|
/** Controls the viewer container background. */
|
|
@@ -76,6 +78,8 @@ declare type ModelViewerSurface = 'dialog' | 'inline' | 'page';
|
|
|
76
78
|
|
|
77
79
|
export declare type ModelViewerWidgetMode = 'advanced-ar-view' | 'ar-view' | 'embedded-3d-viewer' | 'ar-viewer' | 'qr-code';
|
|
78
80
|
|
|
81
|
+
export declare type SizeAxis = 'x' | 'y' | 'z';
|
|
82
|
+
|
|
79
83
|
declare type SizeType = 'cm' | 'inch';
|
|
80
84
|
|
|
81
85
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -6529,12 +6529,32 @@ async function publicApiControllerReadObjectByTinuuid({ tinuuid }, params, confi
|
|
|
6529
6529
|
});
|
|
6530
6530
|
return res.data;
|
|
6531
6531
|
}
|
|
6532
|
+
function getErrorResponseStatus(error) {
|
|
6533
|
+
if (!isAxiosError(error)) return;
|
|
6534
|
+
return error.response?.status;
|
|
6535
|
+
}
|
|
6536
|
+
function getModelViewerApiError(error) {
|
|
6537
|
+
if (!isAxiosError(error)) return null;
|
|
6538
|
+
const status = error.response?.status;
|
|
6539
|
+
if (401 === status) return 'unauthorized';
|
|
6540
|
+
if (403 === status) return 'forbidden';
|
|
6541
|
+
if (402 === status) return 'payment-required';
|
|
6542
|
+
return null;
|
|
6543
|
+
}
|
|
6532
6544
|
const WIDGET_SESSION_TOKEN_HEADER = 'x-widget-session-token';
|
|
6533
6545
|
const DEFAULT_REFRESH_THRESHOLD_MS = 30000;
|
|
6534
6546
|
const ALLOWED_PRODUCT_TYPES = new Set([
|
|
6535
6547
|
'core-ar',
|
|
6536
6548
|
'core-ar-shopify'
|
|
6537
6549
|
]);
|
|
6550
|
+
const ASSUMED_HANDOFF_SESSION_TTL_SECONDS = 900;
|
|
6551
|
+
async function activateCoreArWidgetSession(mode, requestConfig) {
|
|
6552
|
+
const activation = await publicApiControllerActivateCoreAR({
|
|
6553
|
+
mode
|
|
6554
|
+
}, requestConfig);
|
|
6555
|
+
if ('string' != typeof activation.productType || !ALLOWED_PRODUCT_TYPES.has(activation.productType)) throw new TypeError('The API key is not enabled for Core AR');
|
|
6556
|
+
return parseWidgetSession(activation.widgetSession);
|
|
6557
|
+
}
|
|
6538
6558
|
class ModelViewerWidgetSession {
|
|
6539
6559
|
apiBaseUrl;
|
|
6540
6560
|
apiKey;
|
|
@@ -6577,6 +6597,19 @@ class ModelViewerWidgetSession {
|
|
|
6577
6597
|
signal
|
|
6578
6598
|
};
|
|
6579
6599
|
}
|
|
6600
|
+
async recoverFromExpiry(signal) {
|
|
6601
|
+
try {
|
|
6602
|
+
await this.refresh();
|
|
6603
|
+
} catch {
|
|
6604
|
+
this.session = this.toSnapshot(await activateCoreArWidgetSession(this.mode, {
|
|
6605
|
+
baseURL: this.apiBaseUrl,
|
|
6606
|
+
headers: {
|
|
6607
|
+
'x-api-key': this.apiKey
|
|
6608
|
+
},
|
|
6609
|
+
signal
|
|
6610
|
+
}));
|
|
6611
|
+
}
|
|
6612
|
+
}
|
|
6580
6613
|
refresh() {
|
|
6581
6614
|
if (this.refreshPromise) return this.refreshPromise;
|
|
6582
6615
|
this.refreshPromise = this.issueWidgetToken({
|
|
@@ -6603,37 +6636,38 @@ class ModelViewerWidgetSession {
|
|
|
6603
6636
|
}
|
|
6604
6637
|
}
|
|
6605
6638
|
async function createModelViewerWidgetSession({ apiBaseUrl, apiKey, initialWidgetSessionToken, mode, signal }) {
|
|
6606
|
-
|
|
6639
|
+
if (initialWidgetSessionToken) return new ModelViewerWidgetSession({
|
|
6640
|
+
expiresIn: ASSUMED_HANDOFF_SESSION_TTL_SECONDS,
|
|
6641
|
+
sid: initialWidgetSessionToken,
|
|
6642
|
+
token: initialWidgetSessionToken
|
|
6643
|
+
}, {
|
|
6644
|
+
apiBaseUrl,
|
|
6645
|
+
apiKey,
|
|
6646
|
+
mode
|
|
6647
|
+
});
|
|
6648
|
+
const activationData = await activateCoreArWidgetSession(mode, {
|
|
6607
6649
|
baseURL: apiBaseUrl,
|
|
6608
6650
|
headers: {
|
|
6609
6651
|
'x-api-key': apiKey
|
|
6610
6652
|
},
|
|
6611
6653
|
signal
|
|
6612
|
-
};
|
|
6613
|
-
|
|
6614
|
-
const refreshed = await publicApiControllerIssueWidgetToken({
|
|
6615
|
-
mode,
|
|
6616
|
-
token: initialWidgetSessionToken
|
|
6617
|
-
}, requestConfig);
|
|
6618
|
-
return new ModelViewerWidgetSession(parseWidgetSession(refreshed), {
|
|
6619
|
-
apiBaseUrl,
|
|
6620
|
-
apiKey,
|
|
6621
|
-
mode
|
|
6622
|
-
});
|
|
6623
|
-
} catch (error) {
|
|
6624
|
-
if (signal?.aborted) throw error;
|
|
6625
|
-
}
|
|
6626
|
-
const activation = await publicApiControllerActivateCoreAR({
|
|
6627
|
-
mode
|
|
6628
|
-
}, requestConfig);
|
|
6629
|
-
if ('string' != typeof activation.productType || !ALLOWED_PRODUCT_TYPES.has(activation.productType)) throw new TypeError('The API key is not enabled for Core AR');
|
|
6630
|
-
return new ModelViewerWidgetSession(parseWidgetSession(activation.widgetSession), {
|
|
6654
|
+
});
|
|
6655
|
+
return new ModelViewerWidgetSession(activationData, {
|
|
6631
6656
|
apiBaseUrl,
|
|
6632
6657
|
apiKey,
|
|
6633
6658
|
mode
|
|
6634
6659
|
});
|
|
6635
6660
|
}
|
|
6636
6661
|
async function fetchModelViewerObject(tinuuid, variantId, session, signal) {
|
|
6662
|
+
try {
|
|
6663
|
+
return await readObjectWithSession(tinuuid, variantId, session, signal);
|
|
6664
|
+
} catch (error) {
|
|
6665
|
+
if (401 !== getErrorResponseStatus(error)) throw error;
|
|
6666
|
+
await session.recoverFromExpiry(signal);
|
|
6667
|
+
return readObjectWithSession(tinuuid, variantId, session, signal);
|
|
6668
|
+
}
|
|
6669
|
+
}
|
|
6670
|
+
async function readObjectWithSession(tinuuid, variantId, session, signal) {
|
|
6637
6671
|
return publicApiControllerReadObjectByTinuuid({
|
|
6638
6672
|
tinuuid
|
|
6639
6673
|
}, {
|
|
@@ -6766,20 +6800,45 @@ function useObjectData(tinuuid, initialHid, options) {
|
|
|
6766
6800
|
widgetSession: data?.widgetSession ?? null
|
|
6767
6801
|
};
|
|
6768
6802
|
}
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6803
|
+
const RECOVERY_STORAGE_KEY = 'vizbl-model-viewer-blank-canvas-recovery';
|
|
6804
|
+
const RENDER_CHECK_DELAY_MS = 2000;
|
|
6805
|
+
const SAMPLE_SIZE = 64;
|
|
6806
|
+
const NON_ZERO_CHANNEL_THRESHOLD = 8;
|
|
6807
|
+
function scheduleBlankCanvasRecovery(modelViewerEl) {
|
|
6808
|
+
window.setTimeout(()=>{
|
|
6809
|
+
if (isCanvasBlank(modelViewerEl) && !hasAlreadyRecovered()) {
|
|
6810
|
+
markRecovered();
|
|
6811
|
+
window.location.reload();
|
|
6812
|
+
}
|
|
6813
|
+
}, RENDER_CHECK_DELAY_MS);
|
|
6772
6814
|
}
|
|
6773
|
-
function
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6815
|
+
function hasAlreadyRecovered() {
|
|
6816
|
+
try {
|
|
6817
|
+
return '1' === window.sessionStorage.getItem(RECOVERY_STORAGE_KEY);
|
|
6818
|
+
} catch {
|
|
6819
|
+
return false;
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6822
|
+
function markRecovered() {
|
|
6823
|
+
try {
|
|
6824
|
+
window.sessionStorage.setItem(RECOVERY_STORAGE_KEY, '1');
|
|
6825
|
+
} catch {}
|
|
6826
|
+
}
|
|
6827
|
+
function isCanvasBlank(modelViewerEl) {
|
|
6828
|
+
const canvas = modelViewerEl.shadowRoot?.querySelector('canvas.show');
|
|
6829
|
+
if (!canvas || 0 === canvas.width || 0 === canvas.height) return false;
|
|
6830
|
+
const gl = canvas.getContext('webgl2') ?? canvas.getContext('webgl');
|
|
6831
|
+
if (!gl) return false;
|
|
6832
|
+
const size = Math.min(SAMPLE_SIZE, canvas.width, canvas.height);
|
|
6833
|
+
const x = Math.max(0, Math.floor((canvas.width - size) / 2));
|
|
6834
|
+
const y = Math.max(0, Math.floor((canvas.height - size) / 2));
|
|
6835
|
+
const pixels = new Uint8Array(size * size * 4);
|
|
6836
|
+
gl.readPixels(x, y, size, size, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
6837
|
+
for(let i = 0; i < pixels.length; i += 4)if (pixels[i] > NON_ZERO_CHANNEL_THRESHOLD || pixels[i + 1] > NON_ZERO_CHANNEL_THRESHOLD || pixels[i + 2] > NON_ZERO_CHANNEL_THRESHOLD || pixels[i + 3] > NON_ZERO_CHANNEL_THRESHOLD) return false;
|
|
6838
|
+
return true;
|
|
6780
6839
|
}
|
|
6781
6840
|
const ModelViewerContext = /*#__PURE__*/ createContext(null);
|
|
6782
|
-
function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExperience, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, hid, launchAr, layout, background, sizeType, viewerSurface }) {
|
|
6841
|
+
function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExperience, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, hid, launchAr, layout, background, sizeType, dimensionAxes, viewerSurface }) {
|
|
6783
6842
|
const { object, material, error, isLoading, setMaterialHid: setObjectMaterialHid, widgetSession } = useObjectData(tinuuid, hid, {
|
|
6784
6843
|
apiBaseUrl,
|
|
6785
6844
|
apiKey,
|
|
@@ -6865,6 +6924,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
|
|
|
6865
6924
|
};
|
|
6866
6925
|
const handleLoad = ()=>{
|
|
6867
6926
|
setIsModelLoading(false);
|
|
6927
|
+
scheduleBlankCanvasRecovery(modelViewerEl);
|
|
6868
6928
|
};
|
|
6869
6929
|
const handleError = ()=>{
|
|
6870
6930
|
setIsModelLoading(false);
|
|
@@ -6906,6 +6966,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
|
|
|
6906
6966
|
background,
|
|
6907
6967
|
mode,
|
|
6908
6968
|
sizeType,
|
|
6969
|
+
dimensionAxes,
|
|
6909
6970
|
isLoading,
|
|
6910
6971
|
isModelLoading,
|
|
6911
6972
|
state,
|
|
@@ -6932,6 +6993,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
|
|
|
6932
6993
|
background,
|
|
6933
6994
|
mode,
|
|
6934
6995
|
sizeType,
|
|
6996
|
+
dimensionAxes,
|
|
6935
6997
|
isLoading,
|
|
6936
6998
|
isModelLoading,
|
|
6937
6999
|
state,
|
|
@@ -6951,6 +7013,11 @@ function useModelViewer() {
|
|
|
6951
7013
|
if (!context) throw new Error('useModelViewer must be used within a ModelViewerProvider');
|
|
6952
7014
|
return context;
|
|
6953
7015
|
}
|
|
7016
|
+
function resolveDirectArExperience(mode, arExperience) {
|
|
7017
|
+
if ('ar-view' === mode) return 'standard';
|
|
7018
|
+
if ('advanced-ar-view' === mode || 'ar-viewer' === mode) return 'advanced';
|
|
7019
|
+
if ('qr-code' === mode) return arExperience;
|
|
7020
|
+
}
|
|
6954
7021
|
function getUserAgent() {
|
|
6955
7022
|
if ("u" < typeof navigator) return '';
|
|
6956
7023
|
return navigator.userAgent || navigator.vendor || '';
|
|
@@ -7055,7 +7122,7 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
|
|
|
7055
7122
|
object?.tinuuid,
|
|
7056
7123
|
tinuuid
|
|
7057
7124
|
]);
|
|
7058
|
-
const directArExperience =
|
|
7125
|
+
const directArExperience = resolveDirectArExperience(mode, arExperience);
|
|
7059
7126
|
const directArLaunchOptions = external_react_useMemo(()=>{
|
|
7060
7127
|
const native = material?.native;
|
|
7061
7128
|
if (!directArExperience || !object || !native?.glbUrl || !native.usdzUrl || "u" < typeof window) return null;
|
|
@@ -7333,6 +7400,10 @@ const DIMENSION_LABEL_CONFIGS = [
|
|
|
7333
7400
|
}
|
|
7334
7401
|
];
|
|
7335
7402
|
const DIMENSION_LABEL_SLOTS = DIMENSION_LABEL_CONFIGS.map((config)=>config.slot);
|
|
7403
|
+
const DIMENSION_LABEL_AXIS_BY_SLOT = new Map(DIMENSION_LABEL_CONFIGS.map((config)=>[
|
|
7404
|
+
config.slot,
|
|
7405
|
+
config.sizeAxis
|
|
7406
|
+
]));
|
|
7336
7407
|
const LINE_CONNECTIONS = [
|
|
7337
7408
|
{
|
|
7338
7409
|
lineIndex: 0,
|
|
@@ -7376,7 +7447,7 @@ const Hotspots = /*#__PURE__*/ memo(({ hiddenHotspots, isVisible, labels })=>{
|
|
|
7376
7447
|
children: HOTSPOT_CONFIGS.map((hotspot)=>{
|
|
7377
7448
|
const isDimensionLabel = hotspot.isDimensionLabel;
|
|
7378
7449
|
const labelData = labelsMap.get(hotspot.slot);
|
|
7379
|
-
const isHidden = !isVisible || !isDimensionLabel || hiddenHotspots.has(hotspot.slot);
|
|
7450
|
+
const isHidden = !isVisible || !isDimensionLabel || !labelData || hiddenHotspots.has(hotspot.slot);
|
|
7380
7451
|
return /*#__PURE__*/ jsx(button_Button, {
|
|
7381
7452
|
slot: hotspot.slot,
|
|
7382
7453
|
"data-position": hotspot.position,
|
|
@@ -7639,9 +7710,9 @@ function getHotspotConfig(slot) {
|
|
|
7639
7710
|
if (!config) throw new Error(`Missing hotspot config for slot "${slot}"`);
|
|
7640
7711
|
return config;
|
|
7641
7712
|
}
|
|
7642
|
-
function createDimensionLabels(modelViewerEl, sizeType) {
|
|
7713
|
+
function createDimensionLabels(modelViewerEl, sizeType, axes) {
|
|
7643
7714
|
const info = calculateBoundingBoxInfo(modelViewerEl);
|
|
7644
|
-
return DIMENSION_LABEL_CONFIGS.map(({ slot, sizeAxis, offsetMultiplier })=>{
|
|
7715
|
+
return DIMENSION_LABEL_CONFIGS.filter(({ sizeAxis })=>axes.includes(sizeAxis)).map(({ slot, sizeAxis, offsetMultiplier })=>{
|
|
7645
7716
|
const hotspotConfig = getHotspotConfig(slot);
|
|
7646
7717
|
return {
|
|
7647
7718
|
name: slot,
|
|
@@ -7658,7 +7729,7 @@ function syncLabelHotspots(modelViewerEl, labels) {
|
|
|
7658
7729
|
});
|
|
7659
7730
|
});
|
|
7660
7731
|
}
|
|
7661
|
-
function useDimensions({ isVisible }) {
|
|
7732
|
+
function useDimensions({ isVisible, axes }) {
|
|
7662
7733
|
const { glbUrl, isModelLoading, modelViewerEl, sizeType } = useModelViewer();
|
|
7663
7734
|
const [lines, setLines] = useState([]);
|
|
7664
7735
|
const [labels, setLabels] = useState([]);
|
|
@@ -7676,7 +7747,7 @@ function useDimensions({ isVisible }) {
|
|
|
7676
7747
|
]);
|
|
7677
7748
|
const calculateLabels = useCallback(()=>{
|
|
7678
7749
|
if (!modelViewerEl) return [];
|
|
7679
|
-
const dimensionLabels = createDimensionLabels(modelViewerEl, sizeType);
|
|
7750
|
+
const dimensionLabels = createDimensionLabels(modelViewerEl, sizeType, axes);
|
|
7680
7751
|
syncLabelHotspots(modelViewerEl, dimensionLabels);
|
|
7681
7752
|
return dimensionLabels.map((label)=>({
|
|
7682
7753
|
slot: label.name,
|
|
@@ -7685,13 +7756,16 @@ function useDimensions({ isVisible }) {
|
|
|
7685
7756
|
}));
|
|
7686
7757
|
}, [
|
|
7687
7758
|
modelViewerEl,
|
|
7688
|
-
sizeType
|
|
7759
|
+
sizeType,
|
|
7760
|
+
axes
|
|
7689
7761
|
]);
|
|
7690
7762
|
const updateLines = useCallback(()=>{
|
|
7691
7763
|
if (!modelViewerEl) return;
|
|
7692
7764
|
const newLines = [];
|
|
7693
7765
|
const hidden = new Set();
|
|
7694
7766
|
LINE_CONNECTIONS.forEach((connection)=>{
|
|
7767
|
+
const connectionAxis = connection.dimensionHotspot ? DIMENSION_LABEL_AXIS_BY_SLOT.get(connection.dimensionHotspot) : void 0;
|
|
7768
|
+
if (connectionAxis && !axes.includes(connectionAxis)) return;
|
|
7695
7769
|
const dotHotspot1 = modelViewerEl.queryHotspot(connection.hotspot1);
|
|
7696
7770
|
const dotHotspot2 = modelViewerEl.queryHotspot(connection.hotspot2);
|
|
7697
7771
|
const dimensionHotspot = connection.dimensionHotspot ? modelViewerEl.queryHotspot(connection.dimensionHotspot) : null;
|
|
@@ -7713,7 +7787,8 @@ function useDimensions({ isVisible }) {
|
|
|
7713
7787
|
setLines(newLines);
|
|
7714
7788
|
setHiddenHotspots((current)=>areSetsEqual(current, hidden) ? current : hidden);
|
|
7715
7789
|
}, [
|
|
7716
|
-
modelViewerEl
|
|
7790
|
+
modelViewerEl,
|
|
7791
|
+
axes
|
|
7717
7792
|
]);
|
|
7718
7793
|
useEffect(()=>{
|
|
7719
7794
|
if (!glbUrl || !isVisible || !isReady || !modelViewerEl || initializedSrc === glbUrl) return;
|
|
@@ -7758,7 +7833,7 @@ function useDimensions({ isVisible }) {
|
|
|
7758
7833
|
};
|
|
7759
7834
|
}
|
|
7760
7835
|
function ModelViewerContainer({ showDialogCloseButton = false }) {
|
|
7761
|
-
const { glbUrl, isModelLoading, object, previewUrl, state, setContainerEl, setModelViewerEl, usdzUrl, layout, background, trackEvent } = useModelViewer();
|
|
7836
|
+
const { glbUrl, isModelLoading, object, previewUrl, state, setContainerEl, setModelViewerEl, usdzUrl, layout, background, dimensionAxes, trackEvent } = useModelViewer();
|
|
7762
7837
|
const [isDimensionsVisible, setDimensionsVisible] = useState(false);
|
|
7763
7838
|
const isModelLayout = 'model' === layout;
|
|
7764
7839
|
const showViewerLoader = 'loading' === state || 'ready' === state && isModelLoading;
|
|
@@ -7767,7 +7842,8 @@ function ModelViewerContainer({ showDialogCloseButton = false }) {
|
|
|
7767
7842
|
const canToggleDimensions = showControls && !isModelLayout && !isModelLoading;
|
|
7768
7843
|
const isDimensionsActive = isDimensionsVisible && canToggleDimensions;
|
|
7769
7844
|
const { lines, labels, hiddenHotspots } = useDimensions({
|
|
7770
|
-
isVisible: isDimensionsActive
|
|
7845
|
+
isVisible: isDimensionsActive,
|
|
7846
|
+
axes: dimensionAxes
|
|
7771
7847
|
});
|
|
7772
7848
|
const errorState = 'forbidden' === state || 'not-found' === state || 'unauthorized' === state || 'payment-required' === state ? state : null;
|
|
7773
7849
|
if (errorState) return /*#__PURE__*/ jsx("div", {
|
|
@@ -7799,6 +7875,7 @@ function ModelViewerContainer({ showDialogCloseButton = false }) {
|
|
|
7799
7875
|
arScale: "fixed",
|
|
7800
7876
|
shadowIntensity: 1,
|
|
7801
7877
|
interactionPromptThreshold: 100,
|
|
7878
|
+
loading: "eager",
|
|
7802
7879
|
children: [
|
|
7803
7880
|
/*#__PURE__*/ jsx("div", {
|
|
7804
7881
|
slot: "progress-bar"
|
|
@@ -7872,6 +7949,11 @@ function ModelViewerContainer({ showDialogCloseButton = false }) {
|
|
|
7872
7949
|
function normalizeApiKey(apiKey) {
|
|
7873
7950
|
return apiKey?.trim() ?? '';
|
|
7874
7951
|
}
|
|
7952
|
+
const ALL_DIMENSION_AXES = [
|
|
7953
|
+
'x',
|
|
7954
|
+
'y',
|
|
7955
|
+
'z'
|
|
7956
|
+
];
|
|
7875
7957
|
const root_queryClient = new QueryClient({
|
|
7876
7958
|
defaultOptions: {
|
|
7877
7959
|
queries: {
|
|
@@ -7887,7 +7969,7 @@ const root_queryClient = new QueryClient({
|
|
|
7887
7969
|
}
|
|
7888
7970
|
}
|
|
7889
7971
|
});
|
|
7890
|
-
function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip', arExperience, hid, apiBaseUrl = "https://api.vizbl.com", legacyApiBaseUrl = "https://api.vizbl.com/v1", mode = 'embedded-3d-viewer', initialWidgetSessionToken, handoffUrl = "https://integrations.vizbl.com/model-viewer", launchAr, sizeType = 'cm', layout = 'default', background = 'default', showDialogCloseButton = false, viewerSurface = 'inline' }) {
|
|
7972
|
+
function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip', arExperience, hid, apiBaseUrl = "https://api.vizbl.com", legacyApiBaseUrl = "https://api.vizbl.com/v1", mode = 'embedded-3d-viewer', initialWidgetSessionToken, handoffUrl = "https://integrations.vizbl.com/model-viewer", launchAr, sizeType = 'cm', dimensionAxes = ALL_DIMENSION_AXES, layout = 'default', background = 'default', showDialogCloseButton = false, viewerSurface = 'inline' }) {
|
|
7891
7973
|
const normalizedApiKey = normalizeApiKey(apiKey);
|
|
7892
7974
|
return /*#__PURE__*/ jsx(QueryClientProvider, {
|
|
7893
7975
|
client: root_queryClient,
|
|
@@ -7906,6 +7988,7 @@ function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip
|
|
|
7906
7988
|
layout: layout,
|
|
7907
7989
|
background: background,
|
|
7908
7990
|
sizeType: sizeType,
|
|
7991
|
+
dimensionAxes: dimensionAxes,
|
|
7909
7992
|
viewerSurface: viewerSurface,
|
|
7910
7993
|
children: /*#__PURE__*/ jsx(ModelViewerContainer, {
|
|
7911
7994
|
showDialogCloseButton: showDialogCloseButton
|
|
@@ -7913,7 +7996,7 @@ function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip
|
|
|
7913
7996
|
})
|
|
7914
7997
|
});
|
|
7915
7998
|
}
|
|
7916
|
-
function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, initialWidgetSessionToken, handoffUrl, hid, sizeType, ...props }) {
|
|
7999
|
+
function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, initialWidgetSessionToken, handoffUrl, hid, sizeType, dimensionAxes, ...props }) {
|
|
7917
8000
|
const [container, setContainer] = useState(null);
|
|
7918
8001
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
7919
8002
|
children: [
|
|
@@ -7954,6 +8037,7 @@ function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, init
|
|
|
7954
8037
|
handoffUrl: handoffUrl,
|
|
7955
8038
|
hid: hid,
|
|
7956
8039
|
sizeType: sizeType,
|
|
8040
|
+
dimensionAxes: dimensionAxes,
|
|
7957
8041
|
showDialogCloseButton: true,
|
|
7958
8042
|
viewerSurface: "dialog"
|
|
7959
8043
|
})
|
|
@@ -7979,7 +8063,7 @@ function ModelViewerDialog({ tinuuid, apiKey, apiBaseUrl, legacyApiBaseUrl, init
|
|
|
7979
8063
|
]
|
|
7980
8064
|
});
|
|
7981
8065
|
}
|
|
7982
|
-
function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, launchAr, sizeType, layout, background, viewerSurface, className, ...props }) {
|
|
8066
|
+
function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, launchAr, sizeType, dimensionAxes, layout, background, viewerSurface, className, ...props }) {
|
|
7983
8067
|
const [container, setContainer] = useState(null);
|
|
7984
8068
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
7985
8069
|
children: [
|
|
@@ -8020,6 +8104,7 @@ function ModelViewer({ tinuuid, apiKey, appClipBundleId, arExperience, hid, apiB
|
|
|
8020
8104
|
hid: hid,
|
|
8021
8105
|
launchAr: launchAr,
|
|
8022
8106
|
sizeType: sizeType,
|
|
8107
|
+
dimensionAxes: dimensionAxes,
|
|
8023
8108
|
layout: layout,
|
|
8024
8109
|
background: background,
|
|
8025
8110
|
viewerSurface: viewerSurface
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neurodyn/react-model-viewer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"radix-ui": "1.4.3",
|
|
37
37
|
"react-shadow": "^20.6.0",
|
|
38
38
|
"tailwind-merge": "3.4.0",
|
|
39
|
-
"three": "
|
|
39
|
+
"three": "0.182.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@microsoft/api-extractor": "^7.58.0",
|