Start · Sprachen · JavaScript · Referenz · GPUCanvasContext.canvas

GPUCanvasContext.canvas

Eigenschaft

Schreibgeschützte Eigenschaft, die eine Referenz auf das <code>HTMLCanvasElement</code> oder <code>OffscreenCanvas</code> liefert, aus dem der WebGPU-Kontext erstellt wurde.

seit JavaScript WebGPU – Chrome/Edge 113+, Safari 26+, Firefox 141 Kategorie: webapi

Signatur

GPUCanvasContext.canvas

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

Typ
HTMLCanvasElement | OffscreenCanvas
Beschreibung
Das Canvas-Objekt, aus dem der Kontext erstellt wurde. Es ist immer dasselbe Objekt, auf dem 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);
true true

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();
300 150

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);
Neue Größe: 1600 900

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]);
true 300x150

// Wichtig · Fallstricke

  • Kein DOM-Element im Worker: Wurde der Kontext aus einem OffscreenCanvas erstellt, liefert canvas auch ein OffscreenCanvas. Das hat keine Eigenschaften wie clientWidth, style oder addEventListener für Mausereignisse. Prüfe den Typ bei Bedarf mit instanceof.
  • Eigenschaft ist schreibgeschützt: Eine Zuweisung an context.canvas wird im nicht-strikten Modus stillschweigend ignoriert und löst im strikten Modus einen TypeError aus.
  • Größenänderung: Ändert man context.canvas.width oder height, liefert getCurrentTexture() 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/height sind die Pixel der Zeichenfläche, nicht die CSS-Größe. Ohne Anpassung an devicePixelRatio wirkt 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.