Start · Sprachen · JavaScript · Referenz · OrientationSensor.populateMatrix()

OrientationSensor.populateMatrix()

Methode

Schreibt die Rotationsmatrix des neuesten Sensorwerts eines <code>OrientationSensor</code> als 4×4-Matrix in ein übergebenes <code>Float32Array</code>, <code>Float64Array</code> oder <code>DOMMatrix</code>.

seit JavaScript Chrome/Edge 67+, Opera 54+ (Generic Sensor API); n Kategorie: webapi

Signatur

OrientationSensor.prototype.populateMatrix(targetMatrix)

Beschreibung

Die Methode populateMatrix() gehört zur abstrakten Schnittstelle OrientationSensor und steht damit auf den konkreten Sensoren AbsoluteOrientationSensor und RelativeOrientationSensor zur Verfügung. Sie wandelt die intern als Quaternion gespeicherte Geräteausrichtung (siehe OrientationSensor.quaternion) in eine 4×4-Rotationsmatrix um und schreibt das Ergebnis direkt in ein vorhandenes Zielobjekt. Eine neue Matrix wird dabei nicht erzeugt.

So kann man einen einzigen Puffer anlegen und ihn in jedem reading-Event oder in jedem Animationsframe wiederverwenden. Das vermeidet Speicherbereinigung in heißen Render-Schleifen. Die Werte stehen in spaltenweiser Reihenfolge (column-major), genau wie WebGL und die meisten 3D-Bibliotheken (three.js, gl-matrix) sie erwarten. Ein Float32Array kann daher ohne Umwandlung an gl.uniformMatrix4fv() übergeben werden.

Typische Einsatzfälle sind 360°-Ansichten, AR- und VR-Anwendungen, Kompass-Anzeigen oder 3D-Modelle, die sich mit dem Gerät mitdrehen. Wenn Sie nur die Quaternion brauchen, lesen Sie besser direkt sensor.quaternion. Die Matrix lohnt sich vor allem, wenn sie ohnehin an eine Grafik-Pipeline oder an CSS-matrix3d() weitergegeben wird.

Parameter

Name Typ Default Beschreibung
$targetMatrix Pflicht Float32Array | Float64Array | DOMMatrix Zielobjekt, in das die Rotationsmatrix geschrieben wird. Typisierte Arrays müssen mindestens 16 Elemente haben. Die Werte stehen spaltenweise (column-major). Eine DOMMatrix wird entsprechend überschrieben.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Das Ergebnis steht im übergebenen targetMatrix. Bei Fehlern wird eine Ausnahme geworfen: TypeError, wenn ein typisiertes Array weniger als 16 Elemente hat, und NotReadableError (DOMException), wenn der Sensor noch keinen Messwert hat.

Beispiele

Matrix bei jedem Messwert aktualisieren

const sensor = new AbsoluteOrientationSensor({ frequency: 60 });
const rotation = new Float32Array(16); // einmal anlegen, immer wiederverwenden

sensor.addEventListener('reading', () => {
  sensor.populateMatrix(rotation);
  console.log('Erste Spalte:', rotation.slice(0, 4));
});

sensor.addEventListener('error', (event) => {
  console.error(event.error.name, event.error.message);
});

sensor.start();
Erste Spalte: Float32Array(4) [0.98, -0.12, 0.15, 0]

Rotationsmatrix an einen WebGL-Shader übergeben

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// Annahme: program wurde bereits kompiliert und gelinkt
const program = createShaderProgram(gl);
const uRotation = gl.getUniformLocation(program, 'uRotation');

const sensor = new RelativeOrientationSensor({ frequency: 60, referenceFrame: 'screen' });
const modelMatrix = new Float32Array(16);

const render = () => {
  if (sensor.activated && sensor.hasReading) {
    sensor.populateMatrix(modelMatrix);
    gl.useProgram(program);
    gl.uniformMatrix4fv(uRotation, false, modelMatrix); // column-major, keine Transposition nötig
    gl.drawArrays(gl.TRIANGLES, 0, 36);
  }
  requestAnimationFrame(render);
};

sensor.start();
requestAnimationFrame(render);

DOMMatrix für eine CSS-3D-Drehung nutzen, mit Berechtigungsprüfung

const startOrientation = async (element) => {
  const results = await Promise.all(
    ['accelerometer', 'gyroscope', 'magnetometer'].map((name) =>
      navigator.permissions.query({ name })
    )
  );
  if (results.some((r) => r.state === 'denied')) {
    console.warn('Sensorzugriff verweigert');
    return;
  }

  const sensor = new AbsoluteOrientationSensor({ frequency: 30 });
  const matrix = new DOMMatrix();

  sensor.addEventListener('reading', () => {
    try {
      sensor.populateMatrix(matrix);
      element.style.transform = matrix.toString(); // ergibt matrix3d(...)
    } catch (err) {
      if (err.name === 'NotReadableError') console.warn('Noch kein Messwert');
      else throw err;
    }
  });
  sensor.start();
};

startOrientation(document.querySelector('#cube'));

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Methode gibt es nur in Chromium-Browsern (Chrome, Edge, Opera, Samsung Internet). Firefox und Safari unterstützen die Generic Sensor API nicht. Prüfen Sie deshalb vorher mit 'AbsoluteOrientationSensor' in window und sehen Sie gegebenenfalls einen Ersatz über das deviceorientation-Event vor.
  • Sicherer Kontext: Funktioniert nur über HTTPS. Die Permissions Policy muss accelerometer und gyroscope erlauben, beim absoluten Sensor zusätzlich magnetometer. In iframes muss das per allow-Attribut freigegeben werden.
  • Kein Messwert: Wird die Methode vor dem ersten reading-Event oder nach stop() aufgerufen, wirft sie eine NotReadableError-DOMException. Prüfen Sie vorher sensor.hasReading.
  • Puffergröße: Typisierte Arrays mit weniger als 16 Elementen führen zu einem TypeError. Ein normales Array wird nicht akzeptiert.
  • Matrix-Reihenfolge: Die Werte stehen spaltenweise. Wer die Matrix zeilenweise liest oder eigene Rechenroutinen nutzt, erhält sonst die transponierte, also umgekehrte Drehung.
  • Datenschutz: Bewegungssensoren können für Fingerprinting missbraucht werden. Browser begrenzen deshalb teilweise die Frequenz und liefern Werte nur, solange die Seite sichtbar und im Fokus ist.