Signatur
Beschreibung
Die Eigenschaft canvas eines GPUCanvasContext verweist auf das Canvas, auf dem getContext("webgpu") aufgerufen wurde. Je nach Herkunft ist das ein HTMLCanvasElement im DOM oder ein OffscreenCanvas, etwa in einem Web Worker.
Praktisch ist das vor allem dann, wenn Hilfsfunktionen nur den Kontext bekommen, aber trotzdem die Größe des Canvas brauchen. Das kommt häufig vor: beim Anlegen einer Tiefen-Textur mit passender Größe, beim Anpassen an devicePixelRatio oder beim Berechnen des Seitenverhältnisses für eine Projektionsmatrix. So muss man Canvas und Kontext nicht getrennt durch den Code weiterreichen.
Die Eigenschaft ist schreibgeschützt. Die Verbindung zwischen Kontext und Canvas steht für die gesamte Lebensdauer fest. Die Eigenschaften des zurückgegebenen Objekts (z. B. width und height) lassen sich aber ganz normal ändern. Das passt dann die Größe der Textur an, die getCurrentTexture() liefert.
Rückgabewert
getContext("webgpu") aufgerufen wurde.Beispiele
Canvas-Referenz aus dem Kontext abfragen
const canvas = document.querySelector("#gpu-canvas");
const context = canvas.getContext("webgpu");
console.log(context.canvas === canvas);
console.log(context.canvas instanceof HTMLCanvasElement);
Tiefen-Textur passend zur Canvas-Größe anlegen
const createDepthTexture = (device, context) => {
const { width, height } = context.canvas;
return device.createTexture({
size: [width, height],
format: "depth24plus",
usage: GPUTextureUsage.RENDER_ATTACHMENT,
});
};
const init = async () => {
if (!navigator.gpu) throw new Error("WebGPU wird nicht unterstützt");
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const context = document.querySelector("canvas").getContext("webgpu");
context.configure({ device, format: navigator.gpu.getPreferredCanvasFormat() });
const depth = createDepthTexture(device, context);
console.log(depth.width, depth.height);
};
init();
Größe an devicePixelRatio und Layout anpassen
const resizeToDisplaySize = (context) => {
const canvas = context.canvas;
const dpr = window.devicePixelRatio || 1;
const width = Math.floor(canvas.clientWidth * dpr);
const height = Math.floor(canvas.clientHeight * dpr);
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
return true; // Größe hat sich geändert, z. B. Tiefen-Textur neu anlegen
}
return false;
};
const context = document.querySelector("canvas").getContext("webgpu");
const observer = new ResizeObserver(() => {
if (resizeToDisplaySize(context)) console.log("Neue Größe:", context.canvas.width, context.canvas.height);
});
observer.observe(context.canvas);
OffscreenCanvas im Web Worker
// worker.js
self.onmessage = async ({ data }) => {
const context = data.canvas.getContext("webgpu");
console.log(context.canvas instanceof OffscreenCanvas);
console.log(`${context.canvas.width}x${context.canvas.height}`);
};
// main.js
// const offscreen = document.querySelector("canvas").transferControlToOffscreen();
// new Worker("worker.js").postMessage({ canvas: offscreen }, [offscreen]);
// Wichtig · Fallstricke
- Kein DOM-Element im Worker: Wurde der Kontext aus einem
OffscreenCanvaserstellt, liefertcanvasauch einOffscreenCanvas. Das hat keine Eigenschaften wieclientWidth,styleoderaddEventListenerfür Mausereignisse. Prüfe den Typ bei Bedarf mitinstanceof. - Eigenschaft ist schreibgeschützt: Eine Zuweisung an
context.canvaswird im nicht-strikten Modus stillschweigend ignoriert und löst im strikten Modus einenTypeErroraus. - Größenänderung: Ändert man
context.canvas.widthoderheight, liefertgetCurrentTexture()ab dem nächsten Frame eine neue Textur in der neuen Größe. Eigene Texturen wie Tiefenpuffer muss man selbst neu anlegen. - Anzeige- und Pixelgröße sind verschieden:
width/heightsind die Pixel der Zeichenfläche, nicht die CSS-Größe. Ohne Anpassung andevicePixelRatiowirkt die Darstellung auf HiDPI-Bildschirmen unscharf. - Kompatibilität: WebGPU gibt es nur in sicheren Kontexten (HTTPS oder localhost). Prüfe vorher mit
if (navigator.gpu), ob es verfügbar ist. In Firefox und Safari ist die Unterstützung noch nicht auf allen Plattformen vollständig.