Verwendung der Geräteorientierung mit 3D-Transformationen
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Dieser Artikel bietet Tipps zur Verwendung von Geräteorientierungsinformationen in Verbindung mit CSS 3D-Transformationen.
Verwendung der Orientierung zur Drehung eines Elements
Der einfachste Weg, Orientierungsdaten in eine 3D-Transformation umzuwandeln, besteht im Wesentlichen darin, die alpha
, gamma
und beta
Werte als rotateZ
, rotateX
und rotateY
Werte zu verwenden.
Es ist jedoch wichtig zu beachten, dass das Koordinatensystem der Geräteorientierung sich vom CSS-Koordinatensystem unterscheidet. Ersteres ist rechtshändig, und seine Y-Achse ist positiv nach oben, während letzteres ein linkshändiges Koordinatensystem ist, dessen Y-Achse positiv nach unten zeigt. Außerdem sollten die Winkelrotationen der Geräteorientierung immer in einer Z - X' - Y'' Reihenfolge erfolgen, die nicht der Reihenfolge einiger CSS-Transformationen entspricht. Dies sind einige praktische Konsequenzen dieser Unterschiede:
-
Die Reihenfolge der Winkelrotationen ist wichtig, stellen Sie also sicher, dass die alpha-, beta- und gamma-Rotationen in dieser Reihenfolge angewendet werden.
-
Die
rotate3d()
CSS-Transformation und die FunktionenDOMMatrixReadOnly.rotate()
undDOMMatrix.rotateSelf()
wenden Winkelrotationen in einer Z - Y' - X'' Reihenfolge an. Daher ist es nicht möglich, die alpha-, beta- und gamma-Rotationen in der richtigen Reihenfolge mit einem einzigen Aufruf von einer dieser Funktionen zu verwenden. Stattdessen sollten Sie jede Achse einzeln in der richtigen Reihenfolge drehen. -
Aufgrund der oben genannten Unterschiede in den Koordinatensystemen werden Rotationen, wenn sie zum Ursprung hin betrachtet werden, im CSS im Uhrzeigersinn und im Geräteorientierungsspezifikationen gegen den Uhrzeigersinn angewendet. Das bedeutet, dass alpha und beta invertiert werden müssen (die Rotationen um Z und X), weil sie in den beiden Koordinatensystemen in verschiedene Richtungen zeigen. Gamma (die Rotation um Y) sollte jedoch unverändert bleiben.
Hier ein Code-Snippet zur Zusammenfassung:
jsconst elem = document.getElementById("view3d"); window.addEventListener("deviceorientation", (e) => { elem.style.transform = `rotateZ(${-e.alpha}deg) rotateX(${-e.beta}deg) rotateY(${ e.gamma }deg)`; });
Umwandlung von rotate3d()
-Winkeln in deviceorientation
-Winkel
Sollten Sie jemals eine Umwandlung eines rotate3d Achsen-Winkels in Orientierungs-Euler-Winkel benötigen, die von deviceorientation
verwendet werden, können Sie den folgenden Algorithmus verwenden:
// convert a rotate3d axis-angle to deviceorientation angles
function orient(aa) {
const x = aa.x,
y = aa.y,
z = aa.z,
a = aa.a,
c = Math.cos(aa.a),
s = Math.sin(aa.a),
t = 1 - c,
// axis-angle to rotation matrix
rm00 = c + x * x * t,
rm10 = z * s + y * x * t,
rm20 = -y * s + z * x * t,
rm01 = -z * s + x * y * t,
rm11 = c + y * y * t,
rm21 = x * s + z * y * t,
rm02 = y * s + x * z * t,
rm12 = -x * s + y * z * t,
rm22 = c + z * z * t,
TO_DEG = 180 / Math.PI,
ea = [],
n = Math.hypot(rm22, rm20);
// rotation matrix to Euler angles
ea[1] = Math.atan2(-rm21, n);
if (n > 0.001) {
ea[0] = Math.atan2(rm01, rm11);
ea[2] = Math.atan2(rm20, rm22);
} else {
ea[0] = 0;
ea[2] = (rm21 > 0 ? 1 : -1) * Math.atan2(-rm10, rm00);
}
return {
alpha: -ea[0] * TO_DEG - 180,
beta: -ea[1] * TO_DEG,
gamma: ea[2] * TO_DEG,
};
}