简体   繁体   English

设备方向传感器到 CSS 转换

[英]Device orientation sensor to CSS transform

I've created the following widget (see demo here) to mimic the sensors tab on the chrome developer tab:我创建了以下小部件(请参阅此处的演示)来模拟 chrome 开发人员选项卡上的传感器选项卡:


在此处输入图片说明


My code listens to the orientation event of the device and tries to convert the values to fit the css transform scale, like so:我的代码侦听设备的方向事件并尝试将值转换为适合 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)";
    })

However, if I play around enough with the values, my widget and the chrome widget get out of sync.但是,如果我玩弄这些值,我的小部件和 chrome 小部件就会不同步。 Obviously, my calculations are wrong, what am I missing?显然,我的计算是错误的,我错过了什么?

To test my code, just go to the demo open the dev tools sensors tab and play around with the widget.要测试我的代码,只需转到演示打开开发工具传感器选项卡并使用小部件。

Any help would be appreciated.任何帮助,将不胜感激。

Update: to get to the sensors tab: Open dev tools, press Esc, on the second panel click the 3dots on the left and choose sensors.更新:进入传感器选项卡:打开开发工具,按 Esc,在第二个面板上单击左侧的 3 点并选择传感器。

Update: Example of problematic values are:更新:有问题的值的示例是:
alpha: -77.6163阿尔法:-77.6163
beta:-173.4458测试版:-173.4458
gamma:-40.4889伽玛:-40.4889

That is how it is done in chromium and chrome:这就是铬和铬的处理方式:

codepen代码笔

Essential part there is that when we apply gamma angle transformation, the axis is already rotated by previous beta angle transformation.重要的部分是当我们应用gamma角变换时,轴已经被先前的beta角变换旋转了。 So we need to apply gamma rotation angle not to (0, 0, 1) axis but to transformed axis which considers beta angle.因此,我们需要将伽马旋转角应用到考虑 beta 角的变换轴而不是(0, 0, 1)轴。

Source:来源:

 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(); }); });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM