Signatur
Beschreibung
Mit createAnchor() legt man in einer immersiven AR-Sitzung einen Anker an. Das ist ein Punkt in der realen Welt, den das XR-System weiter verfolgt. Beim Tracking passt das Gerät sein Modell der Umgebung ständig an. Koordinaten, die man einfach selbst speichert, „driften“ deshalb mit der Zeit. Ein Anker korrigiert diese Abweichungen: Seine Position bleibt an der physischen Stelle, an der man ihn angelegt hat.
Die Methode nimmt eine XRRigidTransform (Position und Ausrichtung) und einen XRSpace als Bezugssystem. Das Ergebnis ist ein Promise, das mit einem XRAnchor erfüllt wird. Dessen anchorSpace fragt man danach in jedem Frame mit frame.getPose(anchor.anchorSpace, refSpace) ab und platziert darüber virtuelle Objekte.
Typische Einsätze sind z. B. ein virtuelles Möbelstück, das auf dem Boden liegen bleibt, oder Markierungen, die sich der Nutzer merkt. Soll der Anker an einer erkannten Fläche aus einem Hit-Test hängen, nimmt man besser XRHitTestResult.createAnchor(). Damit wird der Anker an die erkannte Fläche gebunden.
Für die Methode muss die Sitzung mit dem Feature "anchors" angefragt worden sein. Außerdem darf man sie nur auf einem aktiven Frame aufrufen, also innerhalb des requestAnimationFrame-Callbacks.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $pose Pflicht | XRRigidTransform | Position und Ausrichtung des gewünschten Ankers, bezogen auf space. |
|
| $space Pflicht | XRSpace | Bezugssystem, in dem pose angegeben ist, z. B. ein XRReferenceSpace ("local") oder der targetRaySpace eines Controllers. |
Rückgabewert
XRAnchor erfüllt. Wird mit einem InvalidStateError (DOMException) abgelehnt, wenn der Frame nicht aktiv ist, oder mit NotSupportedError, wenn das Feature "anchors" nicht aktiviert ist bzw. das Gerät keine Anker anlegen kann.Beispiele
AR-Sitzung mit Anker-Feature starten und Anker vor der Kamera anlegen
const startAR = async () => {
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['anchors', 'local']
});
const refSpace = await session.requestReferenceSpace('local');
const anchors = new Set();
let pendingAnchor = true;
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
if (pendingAnchor) {
pendingAnchor = false;
// 1 Meter vor dem Ursprung des lokalen Raums
const pose = new XRRigidTransform({ x: 0, y: 0, z: -1 });
frame.createAnchor(pose, refSpace)
.then((anchor) => {
anchors.add(anchor);
console.log('Anker erstellt');
})
.catch((err) => console.error('Anker fehlgeschlagen:', err.name));
}
// Alle Anker in jedem Frame abfragen
for (const anchor of anchors) {
const anchorPose = frame.getPose(anchor.anchorSpace, refSpace);
if (anchorPose) {
// Hier ein 3D-Objekt mit anchorPose.transform.matrix platzieren
}
}
};
session.requestAnimationFrame(onFrame);
};
Anker per Controller-Auswahl (select-Event) setzen
// Voraussetzung: session und refSpace wie oben
const anchors = new Set();
session.addEventListener('select', (event) => {
const { frame, inputSource } = event;
// Anker an der aktuellen Pose des Zielstrahls anlegen
const identity = new XRRigidTransform();
frame.createAnchor(identity, inputSource.targetRaySpace)
.then((anchor) => {
anchors.add(anchor);
console.log(`Anker Nr. ${anchors.size} gesetzt`);
})
.catch((err) => console.warn(err.message));
});
Verlorene Anker erkennen und Anker löschen
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
// trackedAnchors enthält alle Anker, die das System gerade verfolgt
for (const anchor of anchors) {
if (!frame.trackedAnchors.has(anchor)) {
console.log('Anker nicht mehr verfolgt – wird entfernt');
anchor.delete(); // Ressourcen beim System freigeben
anchors.delete(anchor);
}
}
};
session.requestAnimationFrame(onFrame);
// Wichtig · Fallstricke
- Feature anfordern: Ohne
"anchors"inrequiredFeaturesoderoptionalFeatureswird das Promise abgelehnt. Wurde das Feature nur optional angefragt, sollte man vor dem Aufruf mittypeof frame.createAnchor === 'function'prüfen, ob es die Methode gibt. - Nur aktive Frames: Man muss die Methode synchron im
requestAnimationFrame-Callback oder in einem Eingabe-Event wieselectaufrufen. Ein gespeicherter Frame, den man später benutzt, führt zu einemInvalidStateError. - Asynchron: Der Anker steht erst in einem späteren Frame zur Verfügung.
getPose()kann anfangsnullliefern, deshalb vor der Nutzung immer prüfen. - Ressourcen: Anker kosten das System Rechenzeit und Speicher. Nicht mehr benötigte Anker gibt man mit
XRAnchor.delete()frei. Wie viele Anker möglich sind, hängt vom Gerät ab. - Kompatibilität: Die Methode ist experimentell. Unterstützt wird sie in Chromium-Browsern auf Android mit ARCore sowie teilweise auf Meta Quest (Meta Quest Browser). Firefox und Safari unterstützen sie nicht. WebXR setzt außerdem einen sicheren Kontext (HTTPS) voraus.
- Datenschutz: Anker verraten Informationen über die Umgebung. Browser können deshalb eine Zustimmung des Nutzers verlangen.