转换为 css 的设备方向数据在使用真实设备时表现异常
Device orientation data transformed to css behaves strange when using a real device
这个问题在继续 :
我创建了一个模仿 phone 方向 (js fiddle) 的 CSS 小部件。使用开发工具传感器选项卡时,小部件可以完美运行,将事件数据转换为 CSS rotate3d 字符串,如下所示(@Andrey 回答):
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)"
);
}
}
但是,如果我使用真实设备(导航到 js fiddle),我会出现奇怪的行为,尤其是在纵向模式下按住 phone 时。这是为什么?我该如何解决?
更新:
看完后this answer, I guess my problem is that I'm using Euler angles. This video解释的很好
但是,我仍在努力将设备方向数据(alpha、beta、gamma)转换为稳定的 CSS 转换。
我正在考虑使用 matrix3d 变换,但缺乏将 alpha、beta 和 gamma 转换为 4X4 矩阵的数学知识。
如有任何帮助,我们将不胜感激。
发现使用 Quaternion is the way to go when encountering that problem (Gimbel lock). I've found an excellent npm library 可以像这样处理数学:
var rad = Math.PI / 180;
window.addEventListener("deviceorientation", function(ev) {
// Update the rotation object
var q = Quaternion.fromEuler(ev.alpha * rad, ev.beta * rad, ev.gamma * rad, 'ZXY');
// Set the CSS style to the element you want to rotate
elm.style.transform = "matrix3d(" + q.conjugate().toMatrix4() + ")";
}, true);
这个问题在继续
我创建了一个模仿 phone 方向 (js fiddle) 的 CSS 小部件。使用开发工具传感器选项卡时,小部件可以完美运行,将事件数据转换为 CSS rotate3d 字符串,如下所示(@Andrey 回答):
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)"
);
}
}
但是,如果我使用真实设备(导航到 js fiddle),我会出现奇怪的行为,尤其是在纵向模式下按住 phone 时。这是为什么?我该如何解决?
更新:
看完后this answer, I guess my problem is that I'm using Euler angles. This video解释的很好
但是,我仍在努力将设备方向数据(alpha、beta、gamma)转换为稳定的 CSS 转换。
我正在考虑使用 matrix3d 变换,但缺乏将 alpha、beta 和 gamma 转换为 4X4 矩阵的数学知识。
如有任何帮助,我们将不胜感激。
发现使用 Quaternion is the way to go when encountering that problem (Gimbel lock). I've found an excellent npm library 可以像这样处理数学:
var rad = Math.PI / 180;
window.addEventListener("deviceorientation", function(ev) {
// Update the rotation object
var q = Quaternion.fromEuler(ev.alpha * rad, ev.beta * rad, ev.gamma * rad, 'ZXY');
// Set the CSS style to the element you want to rotate
elm.style.transform = "matrix3d(" + q.conjugate().toMatrix4() + ")";
}, true);