@neurodyn/react-model-viewer 0.0.5 → 0.0.7

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 CHANGED
@@ -64,6 +64,12 @@ declare interface ModelViewerRootProps {
64
64
  sizeType?: SizeType;
65
65
  /** Which axes' measurements the "Show dimensions" overlay draws. Defaults to all three. */
66
66
  dimensionAxes?: SizeAxis[];
67
+ /** Initial camera angle, in `<model-viewer>`'s own `"theta phi radius"` format. */
68
+ cameraOrbit?: string;
69
+ /** Lower bound for orbit dragging, same format as `cameraOrbit`. Matching `maxCameraOrbit` on an axis locks it. */
70
+ minCameraOrbit?: string;
71
+ /** Upper bound for orbit dragging, same format as `cameraOrbit`. Matching `minCameraOrbit` on an axis locks it. */
72
+ maxCameraOrbit?: string;
67
73
  /** Controls which viewer UI elements are shown. */
68
74
  layout?: ModelViewerLayout;
69
75
  /** Controls the viewer container background. */
package/dist/index.js CHANGED
@@ -2459,6 +2459,10 @@ button, input:where([type="button"], [type="reset"], [type="submit"]) {
2459
2459
  stroke-dasharray: 2;
2460
2460
  }
2461
2461
 
2462
+ .running {
2463
+ animation-play-state: running;
2464
+ }
2465
+
2462
2466
  .group-focus-within\\/editor-mesh-item\\:text-icons-dark:is(:where(.group\\/editor-mesh-item):focus-within *) {
2463
2467
  color: var(--v-icons-dark);
2464
2468
  }
@@ -6838,7 +6842,7 @@ function isCanvasBlank(modelViewerEl) {
6838
6842
  return true;
6839
6843
  }
6840
6844
  const ModelViewerContext = /*#__PURE__*/ createContext(null);
6841
- function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExperience, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, hid, launchAr, layout, background, sizeType, dimensionAxes, viewerSurface }) {
6845
+ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExperience, apiBaseUrl, legacyApiBaseUrl, mode, initialWidgetSessionToken, handoffUrl, hid, launchAr, layout, background, sizeType, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, viewerSurface }) {
6842
6846
  const { object, material, error, isLoading, setMaterialHid: setObjectMaterialHid, widgetSession } = useObjectData(tinuuid, hid, {
6843
6847
  apiBaseUrl,
6844
6848
  apiKey,
@@ -6859,9 +6863,7 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6859
6863
  const accessError = getModelViewerApiError(error);
6860
6864
  if (accessError) return accessError;
6861
6865
  const instantArExperience = 'ar-view' === mode || 'qr-code' === mode && 'standard' === arExperience;
6862
- const advancedArExperience = 'advanced-ar-view' === mode || 'qr-code' === mode && 'advanced' === arExperience;
6863
6866
  if (instantArExperience && object?.policy?.instantArView === false) return 'forbidden';
6864
- if ((advancedArExperience || 'ar-viewer' === mode) && object?.policy?.appClip === false) return 'forbidden';
6865
6867
  if (null != error || !object || !material || !glbUrl) return 'not-found';
6866
6868
  return 'ready';
6867
6869
  }, [
@@ -6967,6 +6969,9 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6967
6969
  mode,
6968
6970
  sizeType,
6969
6971
  dimensionAxes,
6972
+ cameraOrbit,
6973
+ minCameraOrbit,
6974
+ maxCameraOrbit,
6970
6975
  isLoading,
6971
6976
  isModelLoading,
6972
6977
  state,
@@ -6994,6 +6999,9 @@ function ModelViewerProvider({ children, tinuuid, apiKey, appClipBundleId, arExp
6994
6999
  mode,
6995
7000
  sizeType,
6996
7001
  dimensionAxes,
7002
+ cameraOrbit,
7003
+ minCameraOrbit,
7004
+ maxCameraOrbit,
6997
7005
  isLoading,
6998
7006
  isModelLoading,
6999
7007
  state,
@@ -7015,7 +7023,7 @@ function useModelViewer() {
7015
7023
  }
7016
7024
  function resolveDirectArExperience(mode, arExperience) {
7017
7025
  if ('ar-view' === mode) return 'standard';
7018
- if ('advanced-ar-view' === mode || 'ar-viewer' === mode) return 'advanced';
7026
+ if ('advanced-ar-view' === mode || 'ar-viewer' === mode || 'embedded-3d-viewer' === mode) return 'advanced';
7019
7027
  if ('qr-code' === mode) return arExperience;
7020
7028
  }
7021
7029
  function getUserAgent() {
@@ -7037,7 +7045,7 @@ function isSupportedAppClipDevice() {
7037
7045
  if (!isIOSDevice()) return false;
7038
7046
  const versionText = getUserAgent().match(/\bOS (\d+)/)?.[1] ?? getUserAgent().match(/Version\/(\d+)/)?.[1];
7039
7047
  if (!versionText) return false;
7040
- return Number.parseInt(versionText, 10) >= 17;
7048
+ return Number.parseInt(versionText, 10) >= 18;
7041
7049
  }
7042
7050
  function buildAppClipUrl(bundleId, tinuuid, hostname, hid) {
7043
7051
  const url = new URL('https://appclip.apple.com/id');
@@ -7052,8 +7060,13 @@ function buildNativeArUrl(glbUrl, usdzUrl, objectType, ios = isIOSDevice()) {
7052
7060
  const verticalPlacement = 'wall' === objectType || 'ceiling' === objectType ? '&enable_vertical_placement=true' : '';
7053
7061
  return `intent://arvr.google.com/scene-viewer/1.0?file=${encodeURIComponent(new URL(glbUrl).toString())}&resizable=false${verticalPlacement}&mode=ar_preferred#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;end;`;
7054
7062
  }
7055
- function launchDirectAr(options) {
7056
- if ('advanced' === options.experience && isSupportedAppClipDevice()) return void window.location.assign(buildAppClipUrl(options.appClipBundleId, options.tinuuid, options.hostname, options.hid));
7063
+ function launchDirectAr(options, openAppClipInNewTab = false) {
7064
+ if ('advanced' === options.experience && isSupportedAppClipDevice()) {
7065
+ const appClipUrl = buildAppClipUrl(options.appClipBundleId, options.tinuuid, options.hostname, options.hid);
7066
+ if (openAppClipInNewTab) window.open(appClipUrl, '_blank');
7067
+ else window.location.assign(appClipUrl);
7068
+ return;
7069
+ }
7057
7070
  const link = document.createElement('a');
7058
7071
  const image = document.createElement('img');
7059
7072
  link.rel = 'ar';
@@ -7200,6 +7213,11 @@ function AR({ disabled, onClick, onBeforeActivateAr, size = 'lg', ...props }) {
7200
7213
  if (await launchArOverride(launchAr, arTarget)) return void onBeforeActivateAr?.();
7201
7214
  if (directArLaunchOptions && isMobileArDevice()) {
7202
7215
  onBeforeActivateAr?.();
7216
+ if ('advanced' === directArLaunchOptions.experience && isSupportedAppClipDevice()) {
7217
+ launchDirectAr(directArLaunchOptions, true);
7218
+ trackEvent('ar_launched');
7219
+ return;
7220
+ }
7203
7221
  await flushWidgetEvent(trackEvent('ar_launched'));
7204
7222
  launchDirectAr(directArLaunchOptions);
7205
7223
  } else if (modelViewerEl.canActivateAR) {
@@ -7833,7 +7851,7 @@ function useDimensions({ isVisible, axes }) {
7833
7851
  };
7834
7852
  }
7835
7853
  function ModelViewerContainer({ showDialogCloseButton = false }) {
7836
- const { glbUrl, isModelLoading, object, previewUrl, state, setContainerEl, setModelViewerEl, usdzUrl, layout, background, dimensionAxes, trackEvent } = useModelViewer();
7854
+ const { glbUrl, isModelLoading, object, previewUrl, state, setContainerEl, setModelViewerEl, usdzUrl, layout, background, dimensionAxes, cameraOrbit, minCameraOrbit, maxCameraOrbit, trackEvent } = useModelViewer();
7837
7855
  const [isDimensionsVisible, setDimensionsVisible] = useState(false);
7838
7856
  const isModelLayout = 'model' === layout;
7839
7857
  const showViewerLoader = 'loading' === state || 'ready' === state && isModelLoading;
@@ -7871,6 +7889,9 @@ function ModelViewerContainer({ showDialogCloseButton = false }) {
7871
7889
  poster: previewUrl ?? void 0,
7872
7890
  ar: true,
7873
7891
  cameraControls: true,
7892
+ cameraOrbit: cameraOrbit,
7893
+ minCameraOrbit: minCameraOrbit,
7894
+ maxCameraOrbit: maxCameraOrbit,
7874
7895
  arModes: "webxr scene-viewer quick-look",
7875
7896
  arScale: "fixed",
7876
7897
  shadowIntensity: 1,
@@ -7969,7 +7990,7 @@ const root_queryClient = new QueryClient({
7969
7990
  }
7970
7991
  }
7971
7992
  });
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' }) {
7993
+ 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, cameraOrbit, minCameraOrbit, maxCameraOrbit, layout = 'default', background = 'default', showDialogCloseButton = false, viewerSurface = 'inline' }) {
7973
7994
  const normalizedApiKey = normalizeApiKey(apiKey);
7974
7995
  return /*#__PURE__*/ jsx(QueryClientProvider, {
7975
7996
  client: root_queryClient,
@@ -7989,6 +8010,9 @@ function ModelViewerRoot({ tinuuid, apiKey, appClipBundleId = 'com.us.vizbl.Clip
7989
8010
  background: background,
7990
8011
  sizeType: sizeType,
7991
8012
  dimensionAxes: dimensionAxes,
8013
+ cameraOrbit: cameraOrbit,
8014
+ minCameraOrbit: minCameraOrbit,
8015
+ maxCameraOrbit: maxCameraOrbit,
7992
8016
  viewerSurface: viewerSurface,
7993
8017
  children: /*#__PURE__*/ jsx(ModelViewerContainer, {
7994
8018
  showDialogCloseButton: showDialogCloseButton
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.5",
4
+ "version": "0.0.7",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },