使用具有3D变换的设备方向

时间:2015-04-18 10:49:20

标签: css3 3d rotation firefox-os device-orientation

有一个项目想要实现一个立方体,该立方体具有东/西/上/地/北/南的边,这些边应该始终指向相应的地理位置。从deviceorientation API收集必要的数据:http://cube.ffos.lolcathost.org/

我和很多其他用户都想知道为什么这个应用程序没有做它应该做的事情。 (它应该在Firefox OS或任何带有Firefox的Android设备上运行。)除了代码似乎做了很多不必要的事情并且编码风格是一种耻辱之外,我不太明白他在做什么那里。

然后我发现了关于如何在MDN上做类似事情的提示:https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Using_device_orientation_with_3D_transforms

这两种方法似乎都显然是错误的:他们认为只需按正确的顺序应用rotateXrotateYrotateZ,就可以简单地反转设备方向。

deviceorientation事件提供的角度(alpha,beta,gamma)有明确的定义:http://www.w3.org/TR/orientation-event/#deviceorientation它表示相应的旋转轴是旋转轴(设备)的轴帧。因此,围绕z轴旋转角度α,然后围绕(现在旋转!)x轴旋转角度β,然后围绕(现在两次旋转!)y轴旋转角度γ。

因为对于CSS变换,参考帧始终是设备帧,要反转这些步骤,您需要手动保持旋转旋转轴。

var b = e.beta,
    g = -e.gamma,
    a = e.alpha,
    axis_y = Array(0,1,0),
    axis_x = rotate(Array(1,0,0), axis_y, g),
    axis_z = rotate(rotate(Array(0,0,1), axis_y, g), axis_x, b);

因此,CSS转换看起来像这样:

document.getElementById("cube").style.transform =
    "rotate3d(" + axis_z[0] + ", " + axis_z[1] + ", " + axis_z[2] + ", " + a + "deg) " +
    "rotate3d(" + axis_x[0] + ", " + axis_x[1] + ", " + axis_x[2] + ", " + b + "deg) " +
    "rotate3d(" + axis_y[0] + ", " + axis_y[1] + ", " + axis_y[2] + ", " + g + "deg)";

请注意,对于CSS变换函数rotate3d“,旋转是顺时针的,因为从轴向量的末端看向原点”,而对于提供的alpha-beta-gamma,围绕轴的正向旋转是沿轴的正方向观察时为顺时针方向。考虑到CSS变换的y轴指向屏幕的底部,我们只需要在我们的上下文中反转伽马角度。

以下是我对此的实现:http://tovotu.de/tests/compass/index.html

我的问题是:这是实现这个的正确/最佳方式吗?还是有办法在不旋转多次旋转轴的情况下进行此操作?

1 个答案:

答案 0 :(得分:1)

我自己正在使用Device Orientation API,但它只是表面上看 - 我正在独立获得beta和gamma值并将它们应用于球的速度,以便在一个名为Cyber​​的简单游戏演示中将其滚动到屏幕上Orb使用Phaser框架创建并在Canvas上渲染(您可以在MDN articleMozilla Hacks post中找到更多详细信息。)

CSS 3D变换实际上不是我的事,但在我看来 - 如果它有效,那就去吧。它看起来很简单并且完成工作,所以不需要过度复杂化。如果有人知道更好的方法,我也希望看到它。