Signatur
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 Ankerhas(anchor): prüft, ob ein Anker in der Sammlung istforEach(callback): ruft die Rückruffunktion für jeden Anker aufentries(),keys()undvalues()sowie[Symbol.iterator]fürfor...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
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);
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);
};
// 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 inrequiredFeaturesoderoptionalFeaturesanfordern. Fehlt sie, bleibttrackedAnchorsleer oder ist nicht verfügbar. - Nur innerhalb des Frames gültig:
frame.trackedAnchorsundgetPose()darfst du nur im Rückruf vonrequestAnimationFramefür den aktiven Frame verwenden. Ein Zugriff außerhalb davon, etwa nach einemawait, führt zu einerInvalidStateError-Ausnahme. - Die Sammlung ist schreibgeschützt.
add(),delete()undclear()gibt es nicht. Zum Entfernen rufst duXRAnchor.delete()auf. - Ein neu angelegter Anker taucht erst ab einem späteren Frame in
trackedAnchorsauf, nicht sofort nach dem Auflösen des Promise. getPose()kannnullliefern, 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-trackingnötig.