1/**2 * Photo key (backlog, user rule: never freeze the run): `P` exports a3 * still of the live spectacle. The WebGL canvas holds only the scene (the4 * HUD is DOM), so a capture is already clean; the scene is re-rendered5 * immediately before reading the canvas because the default framebuffer6 * is not preserved between frames (preserveDrawingBuffer: false).7 */8import type { SceneCtx } from "./scene.ts";910export interface PhotoKey {11 /** Shots taken this session (CUA/tests). */12 readonly count: number;13 dispose(): void;14}1516export function installPhotoKey(17 ctx: SceneCtx,18 filename: () => string,19): PhotoKey {20 let count = 0;21 const onKey = (ev: KeyboardEvent) => {22 if (ev.key !== "p" && ev.key !== "P") return;23 ctx.renderer.render(ctx.scene, ctx.camera);24 ctx.renderer.domElement.toBlob((blob: Blob | null) => {25 if (!blob) return;26 const a = document.createElement("a");27 a.href = URL.createObjectURL(blob);28 a.download = `${filename()}.png`;29 a.click();30 URL.revokeObjectURL(a.href);31 }, "image/png");32 count++;33 };34 addEventListener("keydown", onKey);35 return {36 get count() {37 return count;38 },39 dispose() {40 removeEventListener("keydown", onKey);41 },42 };43}