Ver Fonte

view USDZ in AR on iOS

Sukolsak Sakshuwong há 3 anos atrás
pai
commit
93d33bca80
2 ficheiros alterados com 33 adições e 1 exclusões
  1. 30 1
      src/extensions/geo-export/ui.tsx
  2. 3 0
      src/mol-plugin-ui/controls/icons.tsx

+ 30 - 1
src/extensions/geo-export/ui.tsx

@@ -7,7 +7,7 @@
 import { merge } from 'rxjs';
 import { CollapsableControls, CollapsableState } from '../../mol-plugin-ui/base';
 import { Button } from '../../mol-plugin-ui/controls/common';
-import { GetAppSvg, CubeSendSvg } from '../../mol-plugin-ui/controls/icons';
+import { GetAppSvg, CubeScanSvg, CubeSendSvg } from '../../mol-plugin-ui/controls/icons';
 import { ParameterControls } from '../../mol-plugin-ui/controls/parameters';
 import { download } from '../../mol-util/download';
 import { GeometryParams, GeometryControls } from './controls';
@@ -18,6 +18,7 @@ interface State {
 
 export class GeometryExporterUI extends CollapsableControls<{}, State> {
     private _controls: GeometryControls | undefined;
+    private isARSupported: boolean | undefined;
 
     get controls() {
         return this._controls || (this._controls = new GeometryControls(this.plugin));
@@ -32,6 +33,9 @@ export class GeometryExporterUI extends CollapsableControls<{}, State> {
     }
 
     protected renderControls(): JSX.Element {
+        if (this.isARSupported === undefined) {
+            this.isARSupported = !!document.createElement('a').relList?.supports?.('ar');
+        }
         const ctrl = this.controls;
         return <>
             <ParameterControls
@@ -45,6 +49,13 @@ export class GeometryExporterUI extends CollapsableControls<{}, State> {
                 disabled={this.state.busy || !this.plugin.canvas3d?.reprCount.value}>
                 Save
             </Button>
+            {this.isARSupported && ctrl.behaviors.params.value.format === 'usdz' &&
+                <Button icon={CubeScanSvg}
+                    onClick={this.viewInAR} style={{ marginTop: 1 }}
+                    disabled={this.state.busy || !this.plugin.canvas3d?.reprCount.value}>
+                    View in AR
+                </Button>
+            }
         </>;
     }
 
@@ -75,4 +86,22 @@ export class GeometryExporterUI extends CollapsableControls<{}, State> {
             this.setState({ busy: false });
         }
     }
+
+    viewInAR = async () => {
+        try {
+            this.setState({ busy: true });
+            const data = await this.controls.exportGeometry();
+            this.setState({ busy: false });
+            const a = document.createElement('a');
+            a.rel = 'ar';
+            a.href = URL.createObjectURL(data.blob);
+            // For in-place viewing of USDZ on iOS, the link must contain a single child that is either an img or picture.
+            // https://webkit.org/blog/8421/viewing-augmented-reality-assets-in-safari-for-ios/
+            a.appendChild(document.createElement('img'));
+            setTimeout(() => URL.revokeObjectURL(a.href), 4E4); // 40s
+            setTimeout(() => a.dispatchEvent(new MouseEvent('click')));
+        } catch {
+            this.setState({ busy: false });
+        }
+    }
 }

+ 3 - 0
src/mol-plugin-ui/controls/icons.tsx

@@ -41,6 +41,9 @@ export function MoleculeSvg() { return _Molecule; }
 const _CubeOutline = <svg width='24px' height='24px' viewBox='0 0 24 24' strokeWidth='0.1px'><path d="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L6.04,7.5L12,10.85L17.96,7.5L12,4.15M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V9.21L13,12.58V19.29L19,15.91Z" /></svg>;
 export function CubeOutlineSvg() { return _CubeOutline; }
 
+const _CubeScan = <svg width='24px' height='24px' viewBox='0 0 24 24' strokeWidth='0.1px'><path d="M17,22V20H20V17H22V20.5C22,20.89 21.84,21.24 21.54,21.54C21.24,21.84 20.89,22 20.5,22H17M7,22H3.5C3.11,22 2.76,21.84 2.46,21.54C2.16,21.24 2,20.89 2,20.5V17H4V20H7V22M17,2H20.5C20.89,2 21.24,2.16 21.54,2.46C21.84,2.76 22,3.11 22,3.5V7H20V4H17V2M7,2V4H4V7H2V3.5C2,3.11 2.16,2.76 2.46,2.46C2.76,2.16 3.11,2 3.5,2H7M13,17.25L17,14.95V10.36L13,12.66V17.25M12,10.92L16,8.63L12,6.28L8,8.63L12,10.92M7,14.95L11,17.25V12.66L7,10.36V14.95M18.23,7.59C18.73,7.91 19,8.34 19,8.91V15.23C19,15.8 18.73,16.23 18.23,16.55L12.75,19.73C12.25,20.05 11.75,20.05 11.25,19.73L5.77,16.55C5.27,16.23 5,15.8 5,15.23V8.91C5,8.34 5.27,7.91 5.77,7.59L11.25,4.41C11.5,4.28 11.75,4.22 12,4.22C12.25,4.22 12.5,4.28 12.75,4.41L18.23,7.59Z" /></svg>;
+export function CubeScanSvg() { return _CubeScan; }
+
 const _CubeSend = <svg width='24px' height='24px' viewBox='0 0 24 24' strokeWidth='0.1px'><path d="M16,4L9,8.04V15.96L16,20L23,15.96V8.04M16,6.31L19.8,8.5L16,10.69L12.21,8.5M0,7V9H7V7M11,10.11L15,12.42V17.11L11,14.81M21,10.11V14.81L17,17.11V12.42M2,11V13H7V11M4,15V17H7V15" /></svg>;
 export function CubeSendSvg() { return _CubeSend; }