【问题标题】:Device orientation sensor to CSS transform设备方向传感器到 CSS 转换
【发布时间】:2019-11-01 02:13:20
【问题描述】:

我创建了the following widget (see demo here) 来模仿 chrome 开发人员选项卡上的传感器选项卡:



我的代码监听设备的方向事件并尝试转换值以适应 css 变换比例,如下所示:

let phone = document.querySelector(".phone");
    window.addEventListener('deviceorientation', (event) => {
      phone.style.transform =
        "rotateY(" + ( event.alpha) + "deg) "
        +
        "rotateX(" + (90 - event.beta) + "deg) "
        +
        "rotateZ(" + (event.gamma ) + "deg)";
    })

但是,如果我对这些值进行了足够的调整,我的小部件和 chrome 小部件就会不同步。显然,我的计算是错误的,我错过了什么?

要测试我的代码,只需转到demo 打开开发工具传感器选项卡并使用小部件。

任何帮助将不胜感激。

更新: 进入传感器选项卡:打开开发工具,按 Esc,在第二个面板上单击左侧的 3 点并选择传感器。

更新: 有问题的值示例如下:
阿尔法:-77.6163
测试版:-173.4458
伽玛:-40.4889

【问题讨论】:

标签: javascript css 3d transform orientation


【解决方案1】:

这就是它在铬和铬中的作用:

codepen

重要的是,当我们应用gamma 角度变换时,轴已经被先前的beta 角度变换旋转了。所以我们需要将伽马旋转角应用到(0, 0, 1) 轴上,而不是应用到考虑了β角的变换轴上。

来源:

function degreesToRadians (deg) {
    return deg * Math.PI / 180;
}

class EulerAngles {
  constructor(alpha, beta, gamma) {
    this.alpha = alpha;
    this.beta = beta;
    this.gamma = gamma;
  }
  
  toRotate3DString() {
    const gammaAxisY = -Math.sin(degreesToRadians(this.beta));
    const gammaAxisZ = Math.cos(degreesToRadians(this.beta));
    const axis = {
      alpha: [0, 1, 0],
      beta: [-1, 0, 0],
      gamma: [0, gammaAxisY, gammaAxisZ]
    };
    return (
      "rotate3d(" +
      axis.alpha.join(",") +
      "," +
      this.alpha +
      "deg) " +
      "rotate3d(" +
      axis.beta.join(",") +
      "," +
      this.beta +
      "deg) " +
      "rotate3d(" +
      axis.gamma.join(",") +
      "," +
      this.gamma +
      "deg)"
    );
  }
}

function ready(fn) {
  if (
    document.attachEvent
      ? document.readyState === "complete"
      : document.readyState !== "loading"
  ) {
    fn();
  } else {
    document.addEventListener("DOMContentLoaded", fn);
  }
}

ready(() => {
  let phone = document.querySelector(".phone");
  window.addEventListener("deviceorientation", event => {
    console.log(event);
    const eulerAngles = new EulerAngles(event.alpha, -90 + event.beta, event.gamma)
    phone.style.transform = eulerAngles.toRotate3DString();
  });
});

【讨论】:

  • 您的代码运行良好,但是,当我测试真实设备时,我得到了意想不到的结果(在某些情况下处于纵向模式时为横向)
  • 我也看到了这种行为。但这些是传感器值(即使调试工具处于具有相同角度的横向模式)
  • 我会试着弄清楚,并会告诉你
  • 太棒了!四元数是否解决了真实设备的问题?
猜你喜欢
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多