微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有 A-Frame/AR JS 的基于 Web 的增强现实 (AR) 中的模态图像弹出窗口

如何解决带有 A-Frame/AR JS 的基于 Web 的增强现实 (AR) 中的模态图像弹出窗口

我开发了一个基于网络的 AR 应用程序,其中包含命中测试和对象定位。 应用程序使用摄像头检测表面,并通过点击/触摸事件将 glb 3D 图片放在该表面上。

现在,另一部分是用户点击 glb 图片时,应该弹出一个带有详细图像的模式弹出窗口。但是 pop 在 VR 模式下有效,但在 AR 模式下无效。

Javascript 来了

<script>
// Define a few custom components useful for AR mode. While these are somewhat reusable,// I recommend checking if there are officially supported alternatives before copying
// these into new projects.

// See also https://github.com/aframevr/aframe/pull/4356
AFRAME.registerComponent('hide-in-ar-mode',{
  // Set this object invisible while in AR mode.
  init: function () {
    this.el.sceneEl.addEventListener('enter-vr',(ev) => {
      this.wasVisible = this.el.getAttribute('visible');
      if (this.el.sceneEl.is('ar-mode')) {
        this.el.setAttribute('visible',false);
      }
    });
    this.el.sceneEl.addEventListener('exit-vr',(ev) => {
      if (this.wasVisible) this.el.setAttribute('visible',true);
    });
  }
});

AFRAME.registerComponent('ar-shadows',{
  // Swap an object's material to a transparent shadows-only material while
  // in AR mode. Intended for use with a ground plane. The object is also
  // set visible while in AR mode,this is useful if it's hidden in other
  // modes due to them using a 3D environment.
  schema: {
    opacity: {default: 0.3}
  },init: function () {
    this.el.sceneEl.addEventListener('enter-vr',(ev) => {
      this.wasVisible = this.el.getAttribute('visible');
      if (this.el.sceneEl.is('ar-mode')) {
        this.savedMaterial = this.el.object3D.children[0].material;
        this.el.object3D.children[0].material = new THREE.ShadowMaterial();
        this.el.object3D.children[0].material.opacity = this.data.opacity;
        this.el.setAttribute('visible',true);
      }
    });
    this.el.sceneEl.addEventListener('exit-vr',(ev) => {
      if (this.savedMaterial) {
        this.el.object3D.children[0].material = this.savedMaterial;
        this.savedMaterial = null;
      }
      if (!this.wasVisible) this.el.setAttribute('visible',false);
    });
  }
});

AFRAME.registerComponent('ar-hit-test',{
  init: function () {
    this.xrHitTestSource = null;
    this.viewerSpace = null;
    this.refSpace = null;

    this.el.sceneEl.renderer.xr.addEventListener('sessionend',(ev) => {
      this.viewerSpace = null;
      this.refSpace = null;
      this.xrHitTestSource = null;
    });
    this.el.sceneEl.renderer.xr.addEventListener('sessionstart',(ev) => {
      let session = this.el.sceneEl.renderer.xr.getSession();

      let element = this.el;
      session.addEventListener('select',function () {
        let position = element.getAttribute('position');

        document.getElementById('dino').setAttribute('position',{
              x: (position.x),y: (position.y),z: (position.z)
          });
        document.getElementById('light').setAttribute('position',{
          x: (position.x),y: (position.y + 2.15),z: (position.z)
        });
      });

      session.requestReferenceSpace('viewer').then((space) => {
        this.viewerSpace = space;
        session.requestHitTestSource({space: this.viewerSpace})
            .then((hitTestSource) => {
              this.xrHitTestSource = hitTestSource;
            });
      });

      session.requestReferenceSpace('local-floor').then((space) => {
        this.refSpace = space;
      });
    });
  },tick: function () {
    if (this.el.sceneEl.is('ar-mode')) {
      if (!this.viewerSpace) return;

      let frame = this.el.sceneEl.frame;
      let xrViewerPose = frame.getViewerPose(this.refSpace);

      if (this.xrHitTestSource && xrViewerPose) {
        let hitTestResults = frame.getHitTestResults(this.xrHitTestSource);
        if (hitTestResults.length > 0) {
          let pose = hitTestResults[0].getPose(this.refSpace);

          let inputMat = new THREE.Matrix4();
          inputMat.fromArray(pose.transform.matrix);

          let position = new THREE.Vector3();
          position.setFromMatrixPosition(inputMat);
          this.el.setAttribute('position',position);
        }
      }
    }
  }
});


 AFRAME.registerComponent('clickhandler',{
  init: function() {
          
      },tick: function() {
          if (this.el.sceneEl.is('ar-mode')) {
            var modal = document.getElementById("myModal");
            modal.style.display = "block";
          }
        }
  });
var span = document.getElementById("close");
function close_modal() {
    var modal = document.getElementById("myModal");
    modal.style.display = "none";
}

HTML 部分在这里

<body>
<div id="myModal" class="modal">
  <div class="modal-content">
    <div class="modal-header">
      <span id="close" onclick="close_modal()">&times;</span>
      <h2>Modal Header</h2>
    </div>
    <div class="modal-body">
      <p>Some text in the Modal Body</p>
      <p>Some other text...</p>
    </div>
    <div class="modal-footer">
      <h3>Modal Footer</h3>
    </div>
  </div>
  </div>
<a-scene webxr="requiredFeatures: hit-test,local-floor;" embedded arjs>
  <a-assets>
    <!-- Model source: https://sketchfab.com/3d-models/spinosaurus-2135501583704537907645bf723685e7
             Model author: https://sketchfab.com/VapTor
             Model license: CC Attribution -->
    <a-asset-item id="spinosaurus"
            src="assets/pack.glb"
            response-type="arraybuffer"></a-asset-item>

    <a-asset-item id="reticle"
            src="reticle.gltf"
            response-type="arraybuffer"></a-asset-item>
    </a-assets>

  <a-camera position="0 1.2 0"></a-camera>

  <!-- Environment for 2D and VR viewing. It's auto-hidden in AR mode. -->
  <!-- <a-entity environment="preset: yavapai; skyType: color; skyColor: #ffe4b5; lighting: none; shadow: none; lightPosition: 0 2.15 0"
        hide-in-ar-mode></a-entity> -->

  <a-entity id="dino" position="0 0 0" scale="0.01 0.01 0.01">
      <a-entity position="0 1.15 0" rotation="0 55 0"
          gltf-model="#spinosaurus"
          animation-mixer
          shadow="cast: true; receive: false"></a-entity>

      <!-- This shadow-receiving plane is only visible in AR mode.-->
      <a-plane  height="30" width="30" rotation="-90 0 0"
              shadow="receive: true"
              ar-shadows="opacity: 0.2"
              visible="false"></a-plane>
  </a-entity>

  <a-entity light="type: hemisphere; intensity: 1"></a-entity>
  <a-light type="directional"
       light="castShadow: true;
              shadowMapHeight: 1024;
              shadowMapWidth: 1024;
              shadowCameraLeft: -7;
              shadowCameraRight: 5;
              shadowCameraBottom: -5;
              shadowCameraTop: 5;"
       id="light"
       target="dino"
       position="-2 4 2">
  </a-light>
  <!-- <a-text value="Hello,World!"></a-text> -->

  <a-entity gltf-model="#reticle" scale="0.8 0.8 0.8" ar-hit-test></a-entity>
</a-scene>

<!-- <div id="text">
  <h1>A-Frame Spinosaurus for VR/AR</h1>

  <p>
    Model: <a href="https://sketchfab.com/3d-models/spinosaurus-2135501583704537907645bf723685e7">Spinosaurus</a> by 
    <a href="https://sketchfab.com/VapTor">Vaptor-Studio</a>.
  </p>
  <p>
    Size: <button id="btn_full">Full</button>
    <button id="btn_half">1/2</button>
    <button id="btn_quarter">1/4</button>
  </p>
  
  <p>
    This requires browser support for WebXR's AR mode,for example an
    <a href="https://developers.google.com/ar/discover/supported-devices">ARCore-compatible</a>
    Android phone with Chrome version 81 or higher.
  </p>
  
  <p>
    Powered by <a href="https://aframe.io/blog/aframe-v1.0.0/">A-Frame v1.0.0</a>.
  </p>
</div>
<script>
    function setSize(scale) {
      document.getElementById('dino').setAttribute('scale',{x: scale,y: scale,z: scale});
    }
    document.getElementById('btn_full').onclick = setSize.bind(this,1);
    document.getElementById('btn_half').onclick = setSize.bind(this,0.5);
    document.getElementById('btn_quarter').onclick = setSize.bind(this,0.25);
</script> -->

<!-- include the Glitch button to show what the webpage is about and
      to make it easier for folks to view source and remix -->
<!-- <div class="glitchButton" style="position:fixed;top:20px;right:20px;"></div>
<script src="https://button.glitch.me/button.js"></script> -->

提前致谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。