在移动中走向或离开模型

问题描述 投票:0回答:1

来自 在我之前的回答上加码我得到了一个WebVR页面,在桌面上可以正常工作,但在手机上,我无法走近模型(看起来更像一个天空盒)。

WebVR not very nice

希望能够走向远离模型(用两根手指分别去,远离对方或更近),除了环顾四周。

经过一番搜索,发现 例子 的,我寻找的这个功能在哪里使用。

Space WebVR cool

如何才能让我的案例也能使用同样的手机功能?

html 3d aframe virtual-reality webvr
1个回答
2
投票

1)轨道控制

如果你想让你的体验围绕着一个模型,在它周围移动相机,并放大和缩小--我会说是 轨道控制 就是你要找的东西。

<a-entity camera look-controls 
          orbit-controls="target: 0 1.6 -0.5; initialPosition: 0 5 15"></a-entity>

摄像机将围绕定义的 target. 与移动触摸事件一起工作.检查它与 gltf 模型 此处.

2)用捏合移动相机

如果你想把摄像机向远处或近处移动,据我所知,你必须在一个自定义组件中实现这种行为。一个穷人的版本可能看起来有点像这样。

AFRAME.registerComponent('pinch-controls', {
  init: function() {
    // moveCamera uses variables from 'this' scope
    this.moveCamera.bind(this);

    // we'll use this to get the 'pinch direction'
    this.distance = 0;
    // we'll keep here the camera's current direction
    this.direction = new THREE.Vector3();
    // camera entity reference
    this.camera = document.querySelector("[camera]");

    // listeners
    document.body.addEventListener('touchstart', event => {
      // we're interested only in two - finger pinches
      if (event.touches.length != 2) return 0;
      // calculate the distance
      this.distance = this.calculatePinchDistance(event);
      // we don't want the touch to rotate the camera around
      this.el.setAttribute('look-controls', 'touchEnabled', false);
    }, false);

    document.body.addEventListener('touchend', event => {
      // when the pinch ends - restore the look-controls
      if (event.touches.length != 1) this.el.setAttribute('look-controls', 'touchEnabled', true);
    }, false);

    document.body.addEventListener('touchmove', event => {
      // we're interested only in two - finger pinches
      if (event.touches.length != 2) return 0;

      // compare the distances to determine which direction should we move
      var distance = this.calculatePinchDistance(event);
      let speed = (distance < this.distance) ? -0.2 : 0.2;
      this.moveCamera(speed);

      // keep the distance for the next callback
      this.distance = distance;
    }, false);
  }, 
  calculatePinchDistance(event) {
      var dx = event.touches[0].pageX - event.touches[1].pageX;
      var dy = event.touches[0].pageY - event.touches[1].pageY;
      return Math.sqrt(dx * dx + dy * dy);
  },
  moveCamera: function(speed) {
        // get the camera direction, and multiply it by the desired 'speed'
        this.el.sceneEl.camera.getWorldDirection(this.direction);
        this.direction.multiplyScalar(speed);
        // apply the change to the actual position
        var pos = this.el.getAttribute("position");
        pos.add(this.direction);
        this.el.setAttribute("position", pos);
    }
}

// HTML
// <a-entity camera look-controls pinch-controls></a-entity>

看看吧 此处


如果你想把摄像机朝向模型移动(而不是朝向它所面对的方向),你只需把提取摄像机方向(在 moveCamera)与计算摄像机<->模型方向。

// instead of
// this.el.sceneEl.camera.getWorldDirection(this.direction);
// grab the direction towards the model
this.direction.copy(this.el.object3D.position)
this.direction.add(modelReference.object3D.position)
this.direction.normalize();
// (...)

Tiago编辑。

最后使用的代码是

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Octant Cube - by Dodds, H. & Peres, T.</title>
    <meta name="description" content="Present in the Taxonomy article">
        <script src="https://kit.fontawesome.com/c9500776a0.js" crossorigin="anonymous"></script>
    <script src="misc/codeBtn.js"></script>
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/aframe-orbit-controls.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/aframe-supercraft-loader.js"></script>
    <style>
    #toggleBtn {
        position: fixed;
        z-index: 9999;
        margin: 25px;
        font-size: 3em;
        color: rgb(128, 0, 128);
        cursor: pointer;
    }

    #toggleBtn:hover {
        color: rgba(128, 0, 128, 0.6);
    }
    </style>
    <script>
    // Models swap component
    AFRAME.registerComponent('content-manager', {
        init: function() {
            const btn = document.querySelector("#toggleBtn")
            const castle = document.querySelector("#castle")
            const fish = document.querySelector("#fish")

            btn.addEventListener("click", e => {
                if (castle.getAttribute("visible")) {
                    castle.emit("fadeOut")
                    btn.classList.remove("fa-fish")
                    btn.classList.add("fa-landmark")
                } else {
                    fish.emit("fadeOut")
                    btn.classList.remove("fa-landmark")
                    btn.classList.add("fa-fish")
                }
            })
            fish.addEventListener('animationcomplete__fadeout', e => {
                fish.setAttribute("visible", "false")
                castle.setAttribute("visible", "true")
                castle.emit("fadeIn")
            })
            castle.addEventListener('animationcomplete__fadeout', e => {
                castle.setAttribute("visible", "false")
                fish.setAttribute("visible", "true")
                fish.emit("fadeIn")
            })
        }
    })

    // move the camera on pinching
    AFRAME.registerComponent('pinch-controls', {
        init: function() {
            // bind the methods that use the scope variables
            this.moveCamera.bind(this);

            // use this to keep track whether the user is moving forward or backwards
            this.distance = 0;
            // store the camera direction here
            this.direction = new THREE.Vector3();
            // camera entity reference
            this.camera = document.querySelector("[camera]");

            document.body.addEventListener('touchstart', event => {
                // react only on two finger pinches
                if (event.touches.length != 2) return 0;

                this.distance = this.calculatePinchDistance(event);
                // prevent the look controls to rotate the camera while pinching
                this.el.setAttribute('look-controls', 'touchEnabled', false);
            }, false);

            document.body.addEventListener('touchend', event => {
                // restore the look-controls
                if (event.touches.length != 1) this.el.setAttribute('look-controls', 'touchEnabled', true)
            }, false);
            document.body.addEventListener('wheel', e => {
                this.moveCamera(e.deltaY < 0 ? -0.2 : 0.2);
            })
            document.body.addEventListener('touchmove', event => {
                // we're interested only in pinching
                if (event.touches.length != 2) return 0;

                // calculate the pinch difference and move the camera
                var distance = this.calculatePinchDistance(event);
                let multiplier = (distance < this.distance) ? -0.2 : 0.2;;
                if (!isNaN(multiplier)) this.moveCamera(multiplier);

                // for later use
                this.distance = distance;
            }, false);
        },
        calculatePinchDistance: function(mouseEvent) {
            var dx = event.touches[0].pageX - event.touches[1].pageX;
            var dy = event.touches[0].pageY - event.touches[1].pageY;
            return Math.sqrt(dx * dx + dy * dy);
        },
        moveCamera: function(speed) {
            this.el.sceneEl.camera.getWorldDirection(this.direction);
            this.direction.multiplyScalar(speed);
            var pos = this.el.getAttribute("position");
            pos.add(this.direction);
            this.el.setAttribute("position", pos)
        }
    })
    </script>
  </head>
  <body>
    <a-scene background="color: #FAFAFA">
      <a-assets>
        <a-asset-item id="octant" src="octant.glb"></a-asset-item>
      </a-assets>
      <a-entity position="0 0.347 -4" rotation="0 60 -1"  gltf-model="#octant"  scale="5 5 5" animation__fadeIn="property: scale; dur: 150; from: 0.001 0.001 0.001; to: 0.5 0.5 0.5; easing: easeInQuad; startEvents: fadeIn" animation__fadeOut="property: scale; dur: 150; from: 0.5 0.5 0.5; to: 0.001 0.001 0.001; easing: easeInQuad; startEvents: fadeOut"></a-entity>
      <a-entity camera look-controls 
          orbit-controls="target: 0 1.6 -0.5; initialPosition: 0 5 15"></a-entity>
    </a-scene>
  </body>
</html>

这就是最后的结果

WebVR 3D Octant with orbit controls

© www.soinside.com 2019 - 2024. All rights reserved.