【问题标题】:Rotate webGL canvas to appear landscape-oriented on a portrait-oriented mobile phone旋转 webGL 画布以在面向纵向的手机上显示为横向
【发布时间】:2021-01-15 23:50:59
【问题描述】:

我正在使用框架并尝试完成此任务 - 当移动设备处于纵向时(即设备宽度 = 414 像素和设备高度 = 736 像素),强制画布呈现为“横向” .

我已经通过以下步骤成功完成了这项工作

camera.aspect = 736 / 414; 
camera.updateProjectionMatrix();

renderer.setSize(736, 414);

在 css 中...

.a-canvas {
  transform: rotate(90deg) translate(161px, 161px);
  height: 414px !important;
  width: 736px !important;
}

这一切都很好,除了一件主要的事情......我的场景中有 3D 按钮,当我点击它们时,它们不会与旋转的画布对齐,而是它们的可点击位置保持在与之前相同的位置画布被旋转了。

我尝试在场景的 object3D 上设置 matrixWorldNeedsUpdate = true 以及 updateWorldMatrix() ,但没有成功。我尝试在光线投射器上调用 refreshObjects,但没有成功。我尝试旋转场景和相机,但没有成功。

我不知道还能做什么。任何帮助将不胜感激!

回答:

感谢 Marquizzo 和 gman 的帮助。这是更新的 a-frame 源代码 (v1.0.4) 以使光线投射器正确处理这个强制横向画布

// line: 66884
onMouseMove: (function () {
  var direction = new THREE.Vector3();
  var mouse = new THREE.Vector2();
  var origin = new THREE.Vector3();
  var rayCasterConfig = {origin: origin, direction: direction};

  return function (evt) {
    var bounds = this.canvasBounds;
    var camera = this.el.sceneEl.camera;
    var left;
    var point;
    var top;

    camera.parent.updateMatrixWorld();

    // Calculate mouse position based on the canvas element
    if (evt.type === 'touchmove' || evt.type === 'touchstart') {
      // Track the first touch for simplicity.
      point = evt.touches.item(0);
    } else {
      point = evt;
    }

    left = point.clientX - bounds.left;
    top = point.clientY - bounds.top;
    // mouse.x = (left / bounds.width) * 2 - 1;
    // mouse.y = -(top / bounds.height) * 2 + 1;

    // HAYDEN's CODE: flipping x and y coordinates to force landscape
    // --------------------------------------------------------------
    let clickX = (left / bounds.width) * 2 - 1;
    let clickY = - (top / bounds.height) * 2 + 1;
    mouse.x = -clickY;
    mouse.y = clickX;
    // --------------------------------------------------------------


    origin.setFromMatrixPosition(camera.matrixWorld);
    direction.set(mouse.x, mouse.y, 0.5).unproject(camera).sub(origin).normalize();
    this.el.setAttribute('raycaster', rayCasterConfig);
    if (evt.type === 'touchmove') { evt.preventDefault(); }
  };
})(),

【问题讨论】:

    标签: three.js aframe


    【解决方案1】:

    A-Frame 在内部使用Raycaster 来确定您单击的位置是否击中了对象。您可以在 Three.js 文档中查看 the raycaster needs the mouse x&y coordinates 以确定您单击的位置。 Here's a working demo 这个概念。但是,通过您的设置,x, y 会变成 -y, x。

    我认为您必须编写自己的 Raycaster 函数来触发 click 事件,而不是依赖内置的 AFrame 功能,然后交换 x&y 值:

    function onClick() {
        let clickX = ( event.clientX / window.innerWidth ) * 2 - 1;
        let clickY = - ( event.clientY / window.innerHeight ) * 2 + 1;
        mouse.x = -clickY;
        mouse.y = clickX;
    
        // Then continue with raycaster.setFromCamera(), etc...
    }
    
    window.addEventListener( 'click', onClick, false );
    

    【讨论】:

    • 这行得通,谢谢!我将使用更新的 a-frame 代码编辑我的问题以进一步澄清
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    相关资源
    最近更新 更多