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 von 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 Drehung eines Elements

Der einfachste Weg, um Orientierungsdaten in eine 3D-Transformation zu konvertieren, besteht darin, die Werte alpha, gamma und beta als rotateZ, rotateX und rotateY 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 nach oben positiv, während letzteres ein linkshändiges Koordinatensystem ist, bei dem die Y-Achse nach unten positiv ist. Darüber hinaus sollten die Drehwinkel der Geräteorientierung immer in einer Z - X' - Y'' Reihenfolge ausgeführt werden, die nicht der Reihenfolge einiger CSS-Transformationen entspricht. Dies sind einige der praktischen Konsequenzen dieser Unterschiede:

  • Die Reihenfolge der Winkeldrehungen ist wichtig, daher sollten die Alpha-, Beta- und Gamma-Drehungen in dieser Reihenfolge angewendet werden.

  • Die rotate3d() CSS-Transformation und 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 von einem von ihnen anzuwenden. Stattdessen sollten Sie jede Achse einzeln in der korrekten Reihenfolge drehen.

  • Aufgrund der oben genannten Unterschiede in den Koordinatensystemen, wenn die Blickrichtung zum Ursprung gerichtet ist, werden die Drehungen im CSS im Uhrzeigersinn und in der Geräteorientierungsspezifikation gegen den Uhrzeigersinn angewendet. Das bedeutet, dass Alpha und Beta invertiert werden müssen (die Drehungen um Z und X), da sie in den beiden Koordinatensystemen in verschiedene Richtungen zeigen. Gamma (die Drehung um Y) sollte jedoch unverändert bleiben.

    Hier ist ein Code-Snippet, um es zusammenzufassen:

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

Konvertieren von rotate3d() Winkeln zu deviceorientation Winkeln

Sollten Sie jemals eine Drehachse rotate3d in Orientierungs-Euler-Winkel, die von deviceorientation verwendet werden, 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