Start · Sprachen · JavaScript · Referenz · XRAnchorSet

XRAnchorSet

Schnittstelle

Die schreibgeschützte, Set-ähnliche Sammlung aller <code>XRAnchor</code>-Objekte, die im aktuellen <code>XRFrame</code> verfolgt werden. Du erreichst sie über <code>XRFrame.trackedAnchors</code>.

seit JavaScript WebXR Anchors Module (experimentell) – Chrome/Edge Kategorie: webapi

Signatur

interface XRAnchorSet (setlike&lt;XRAnchor&gt;, schreibgeschützt)

Beschreibung

XRAnchorSet gehört zum WebXR Anchors Module. Die Schnittstelle stellt eine schreibgeschützte, Set-ähnliche Sammlung (setlike<XRAnchor>) von Ankern dar. Einen eigenen Konstruktor gibt es nicht. Du bekommst die Sammlung in jedem Animations-Frame über die Eigenschaft XRFrame.trackedAnchors. Sie enthält alle Anker, die das System in diesem Frame noch verfolgt.

Anker sind feste Punkte in der realen Welt, zum Beispiel ein virtuelles Möbelstück auf dem Boden. Das Gerät lernt seine Umgebung laufend besser kennen und korrigiert dabei die Position der Anker. Deshalb liest du die Pose eines Ankers in jedem Frame neu aus, und zwar mit frame.getPose(anchor.anchorSpace, referenceSpace). Mit XRAnchorSet gehst du dabei über alle aktiven Anker oder prüfst mit has(), ob ein bestimmter Anker noch verfolgt wird.

Wie ein ReadonlySet bietet die Schnittstelle folgende Mitglieder:

  • size: Anzahl der verfolgten Anker
  • has(anchor): prüft, ob ein Anker in der Sammlung ist
  • forEach(callback): ruft die Rückruffunktion für jeden Anker auf
  • entries(), keys() und values() sowie [Symbol.iterator] für for...of

Methoden wie add(), delete() oder clear() gibt es nicht. Neue Anker legst du mit XRFrame.createAnchor() oder XRHitTestResult.createAnchor() an. Entfernen kannst du sie mit XRAnchor.delete().

Rückgabewert

Typ
XRAnchorSet
Beschreibung
Du erhältst die Sammlung über XRFrame.trackedAnchors. Sie gilt nur für den jeweiligen Frame und enthält XRAnchor-Objekte.

Beispiele

AR-Sitzung mit Anker-Unterstützung starten und Anker anlegen

// Muss durch eine Nutzeraktion ausgelöst werden, z. B. einen Klick
const startAR = async () => {
  const session = await navigator.xr.requestSession('immersive-ar', {
    requiredFeatures: ['anchors', 'local']
  });
  const refSpace = await session.requestReferenceSpace('local');
  let anchorCreated = false;

  const onFrame = async (time, frame) => {
    session.requestAnimationFrame(onFrame);

    if (!anchorCreated) {
      anchorCreated = true;
      // Anker 1 m vor dem Ursprung des Referenzraums anlegen
      const pose = new XRRigidTransform({ x: 0, y: 0, z: -1 });
      const anchor = await frame.createAnchor(pose, refSpace);
      console.log('Anker angelegt:', anchor);
    }

    console.log('Verfolgte Anker:', frame.trackedAnchors.size);
  };

  session.requestAnimationFrame(onFrame);
};

document.querySelector('#ar-button').addEventListener('click', startAR);
Anker angelegt: XRAnchor {anchorSpace: XRSpace} Verfolgte Anker: 1

Posen aller verfolgten Anker in jedem Frame auslesen

// Speichert zu jedem Anker das zugehörige 3D-Objekt
const anchoredObjects = new Map(); // XRAnchor -> Szenenobjekt

const onFrame = (time, frame) => {
  frame.session.requestAnimationFrame(onFrame);

  for (const anchor of frame.trackedAnchors) {
    const pose = frame.getPose(anchor.anchorSpace, refSpace);
    const object = anchoredObjects.get(anchor);
    if (pose && object) {
      // Die Position kann sich von Frame zu Frame leicht ändern
      object.matrix.fromArray(pose.transform.matrix);
    }
  }
};

Verlorene Anker mit has() erkennen und aufräumen

const cleanupLostAnchors = (frame) => {
  for (const [anchor, object] of anchoredObjects) {
    if (!frame.trackedAnchors.has(anchor)) {
      // Das System verfolgt den Anker nicht mehr
      object.visible = false;
      anchoredObjects.delete(anchor);
      console.log('Anker verloren, Objekt ausgeblendet');
    }
  }
};

// Anker gezielt löschen, wenn der Nutzer ein Objekt entfernt
const removeObject = (anchor) => {
  anchor.delete(); // ab dem nächsten Frame nicht mehr in trackedAnchors
  anchoredObjects.delete(anchor);
};
Anker verloren, Objekt ausgeblendet

// Wichtig · Fallstricke

  • Experimentelle API: Das Anchors-Modul läuft derzeit nur in Chromium-Browsern auf Android mit ARCore, also Chrome, Edge und Samsung Internet. Firefox und Safari unterstützen es nicht. Prüfe die Unterstützung vorher mit navigator.xr?.isSessionSupported('immersive-ar').
  • Die Funktion 'anchors' musst du beim Start der Sitzung in requiredFeatures oder optionalFeatures anfordern. Fehlt sie, bleibt trackedAnchors leer oder ist nicht verfügbar.
  • Nur innerhalb des Frames gültig: frame.trackedAnchors und getPose() darfst du nur im Rückruf von requestAnimationFrame für den aktiven Frame verwenden. Ein Zugriff außerhalb davon, etwa nach einem await, führt zu einer InvalidStateError-Ausnahme.
  • Die Sammlung ist schreibgeschützt. add(), delete() und clear() gibt es nicht. Zum Entfernen rufst du XRAnchor.delete() auf.
  • Ein neu angelegter Anker taucht erst ab einem späteren Frame in trackedAnchors auf, nicht sofort nach dem Auflösen des Promise.
  • getPose() kann null liefern, wenn das Tracking kurz ausfällt. Prüfe den Wert deshalb immer.
  • WebXR braucht einen sicheren Kontext (HTTPS). In iframes ist zusätzlich die Permissions-Policy xr-spatial-tracking nötig.