Files
feuerwerk/src/viewport/fullscreen.ts
T
adminandClaude Opus 5.5 cab1c0177f
game-maker / gate (push) Successful in 4m10s
game-maker / suite (push) Failing after 11m53s
Show only the game view in fullscreen, in the editor and the link (#267)
A game is easier to judge and to play without the editor around it.
The Game tab and the game link now both have a button that puts the
game view itself into fullscreen, not just the browser window.

- The Game tab header has a fullscreen button on the right. It hides
  toolbar, panels, tab headers and console and keeps the zoom from the
  picker. A running game keeps running.
- A corner button at the top right, or Esc, leaves fullscreen and puts
  the view back into the tab where it was.
- The game link shows the same corner button. Over a running game it
  hides after 2 s without mouse movement and returns on the next move.
- A click on the corner button never reaches the game.
- Stop ends fullscreen. Stop switches back to the Scene tab, and any
  switch away from the Game tab ends fullscreen, so no empty screen is
  left behind.
- src/viewport/fullscreen.ts wraps the Fullscreen API and holds the
  rule for when the button shows. FullscreenCorner.ts is the button
  used by both pages. Two SVG icons are new.
- Editor.showGameFullscreen moves the GameViewport into the root while
  fullscreen is on.

Tests:
- ./check.sh: 195 files, 2815 tests, exit 0 (3 new unit tests).
- e2e 60: 2 new checks for the corner button on the game link.
- e2e 61 (new): 4 checks for fullscreen in the editor.
- Full e2e run (local): ALL PASSED, 1580 checks.
- Counter-checks fail as expected: rule without "no game running",
  no stopPropagation (60h), no end on tab switch (61c), no reparenting
  of the view (61a).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 14:44:14 +02:00

45 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Fullscreen for the game view (#267): the browser's Fullscreen API on the whole page, which is the
* one canvas. What the canvas then shows – only the game – is up to the page that asked.
*/
/** How long the corner button stays after the mouse last moved over a running game. */
export const CORNER_BUTTON_IDLE_SECONDS = 2;
/**
* Whether the corner button shows: always while no game runs, and over a running game only while
* the mouse moves or rests on the button – it would otherwise sit over the picture for good.
*/
export function showsCornerButton(state: {
running: boolean;
idleSeconds: number;
overButton: boolean;
}): boolean {
return !state.running || state.overButton || state.idleSeconds < CORNER_BUTTON_IDLE_SECONDS;
}
export function isFullscreen(): boolean {
return document.fullscreenElement !== null;
}
/** Enters or leaves fullscreen; a browser that refuses leaves everything as it was. */
export async function toggleFullscreen(): Promise<void> {
try {
if (isFullscreen()) await document.exitFullscreen();
else await document.documentElement.requestFullscreen();
} catch (error) {
console.warn('[fullscreen]', error);
}
}
export function leaveFullscreen(): void {
if (isFullscreen()) void document.exitFullscreen().catch((error) => console.warn('[fullscreen]', error));
}
/** Calls `handler` whenever fullscreen starts or ends, by the button or by Esc; returns the call that stops it. */
export function onFullscreenChange(handler: (on: boolean) => void): () => void {
const listener = (): void => handler(isFullscreen());
document.addEventListener('fullscreenchange', listener);
return () => document.removeEventListener('fullscreenchange', listener);
}