Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Verwendung der Geräteorientierung mit 3D-Transformationen

Dieser Artikel bietet Tipps, wie Sie Geräteorientierungsinformationen zusammen mit CSS 3D-Transformationen verwenden können.

Verwendung der Orientierung zur Rotation eines Elements

Der einfachste Weg, Orientierungsdaten in eine 3D-Transformation zu konvertieren, 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 das CSS-Koordinatensystem ein linkshändiges System ist, dessen Y-Achse positiv nach unten zeigt. Darüber hinaus sollten die Winkeldrehungen der Geräteorientierung immer in einer Z - X' - Y'' Reihenfolge erfolgen, die nicht mit der Reihenfolge einiger CSS-Transformationen übereinstimmt. Dies sind einige der praktischen Konsequenzen dieser Unterschiede:

  • Die Reihenfolge der Winkeldrehungen ist wichtig, daher stellen Sie sicher, dass die Alpha-, Beta- und Gamma-Drehungen in dieser Reihenfolge angewandt werden.

  • Die rotate3d() CSS-Transformation sowie die Funktionen DOMMatrixReadOnly.rotate() und DOMMatrix.rotateSelf() wenden Winkeldrehungen in einer Z - Y' - X'' Reihenfolge an, sodass es nicht möglich ist, die Alpha-, Beta- und Gamma-Drehungen in der richtigen Reihenfolge mit einem einzigen Aufruf anzuwenden. Stattdessen sollten Sie jede Achse individuell in der korrekten Reihenfolge drehen.

  • Aufgrund der oben beschriebenen Unterschiede in den Koordinatensystemen werden Rotationen, wenn sie zum Ursprung hin ausgeführt werden, im CSS im Uhrzeigersinn und in der Spezifikation der Geräteorientierung gegen den Uhrzeigersinn angewendet. Das bedeutet, dass Alpha und Beta (die Rotationen um Z und X) invertiert werden müssen, weil sie in den beiden Koordinatensystemen in verschiedene Richtungen zeigen. Gamma (die Rotation um Y) sollte jedoch unverändert bleiben.

    Hier ist ein Codebeispiel zur Zusammenfassung:

    js
    const 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 zu deviceorientation-Winkeln

Sollten Sie jemals einen rotate3d-Achsenwinkel in die von deviceorientation verwendeten Orientierungs-Eulerwinkel umwandeln müssen, können Sie den folgenden Algorithmus verwenden:

js
// 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,
  };
}

Siehe auch