Signatur
Beschreibung
Die Eigenschaft centralAngle legt fest, wie breit der Ausschnitt eines Zylinder-Layers ist. Der Layer wird nicht als voller Zylinder gezeichnet, sondern nur als gebogener Streifen auf dessen Innenseite. centralAngle ist der Mittelpunktswinkel dieses Streifens in Bogenmaß (Radiant). Math.PI / 2 entspricht also einem Viertelkreis (90°), 2 * Math.PI einem vollen Rundum-Zylinder.
Zusammen mit radius und aspectRatio bestimmt der Winkel die Maße der Fläche in der Szene:
- Bogenbreite =
radius * centralAngle(in Metern) - Höhe =
radius * centralAngle / aspectRatio(in Metern)
Zylinder-Layer eignen sich für gebogene UI-Panels, Menüs, Videos oder Text in VR. Weil der Nutzer ungefähr im Zentrum steht, sind alle Punkte der Fläche etwa gleich weit von ihm entfernt. Dadurch bleibt Text am Rand deutlich schärfer als bei einer flachen Fläche. Den Startwert legst du beim Erzeugen über XRWebGLBinding.createCylinderLayer() im Init-Objekt fest. Zur Laufzeit kannst du centralAngle jederzeit neu setzen, etwa um ein Panel aufzuklappen oder zu animieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | number | 0.78539 (π/4, Standard aus XRCylinderLayerInit) | Nur beim Schreiben: neuer Winkel in Bogenmaß, sinnvoll zwischen 0 und 2 * Math.PI. |
Rückgabewert
Beispiele
Gebogenes UI-Panel mit 90° Breite anlegen
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['layers']
});
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const binding = new XRWebGLBinding(session, gl);
const refSpace = await session.requestReferenceSpace('local');
const panel = binding.createCylinderLayer({
space: refSpace,
viewPixelWidth: 1600,
viewPixelHeight: 800,
radius: 2,
centralAngle: Math.PI / 2, // 90°
aspectRatio: 2
});
session.updateRenderState({ layers: [panel] });
console.log(panel.centralAngle.toFixed(4));
Maße des Panels in Metern berechnen
const getCylinderSize = (layer) => {
const arcWidth = layer.radius * layer.centralAngle;
const height = arcWidth / layer.aspectRatio;
return { arcWidth, height };
};
// panel aus dem vorherigen Beispiel
const { arcWidth, height } = getCylinderSize(panel);
console.log(`Breite: ${arcWidth.toFixed(2)} m, Höhe: ${height.toFixed(2)} m`);
Menü per Animation aufklappen
const targetAngle = Math.PI * 0.75; // 135°
const clamp = (v, min, max) => Math.min(Math.max(v, min), max);
panel.centralAngle = 0.05; // fast geschlossen starten
const onFrame = (time, frame) => {
panel.centralAngle = clamp(panel.centralAngle + 0.03, 0, targetAngle);
if (panel.centralAngle < targetAngle) {
frame.session.requestAnimationFrame(onFrame);
}
};
session.requestAnimationFrame(onFrame);
// Wichtig · Fallstricke
- Bogenmaß statt Grad: Die Eigenschaft erwartet Radiant. Grad rechnest du mit
grad * Math.PI / 180um. Wer versehentlich90setzt, bekommt einen Winkel von rund 14 vollen Umdrehungen. - Die Höhe hängt mit: Die Höhe ergibt sich aus
radius * centralAngle / aspectRatio. Vergrößerst du nur den Winkel, wird das Panel auch höher. Soll die Höhe gleich bleiben, musst duaspectRatioim gleichen Verhältnis mitverändern. - Auflösung passt sich nicht an: Die Pixelgröße der Textur (
viewPixelWidth/viewPixelHeight) steht beim Erzeugen fest. Bei einem größeren Winkel wird dieselbe Textur über eine breitere Fläche gestreckt, der Inhalt wirkt dann unschärfer. - Werte außerhalb von 0 bis 2π sind nicht sinnvoll. Begrenze deine Eingaben selbst auf diesen Bereich.
- Browser-Unterstützung: Die WebXR Layers API ist experimentell. Sie läuft vor allem im Meta Quest Browser, in anderen Browsern oft gar nicht oder nur hinter Flags. Fordere das Feature
'layers'an und prüfe vorher, obXRWebGLBinding.prototype.createCylinderLayerexistiert. Die API steht nur in sicheren Kontexten (HTTPS) zur Verfügung.