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>
This commit is contained in:
1 parent
24d360aeec
commit
cab1c0177f
17 files changed
+356
-8
No files matched your search
@@ -2,6 +2,7 @@ import { Text, type TextStyle } from 'pixi.js';
|
||||
import type { World } from '../runtime/World';
|
||||
import { Theme, textStyle, ui } from '../ui';
|
||||
import { cameraOfWorld } from '../viewport/activeCamera';
|
||||
import { FullscreenCorner } from '../viewport/FullscreenCorner';
|
||||
import { routePointer } from '../viewport/gamePointer';
|
||||
import { collectWorldItems } from '../viewport/items';
|
||||
import { cameraView, type View } from '../viewport/view';
|
||||
@@ -27,6 +28,7 @@ export class GameScreen extends WorldViewport {
|
||||
/** Asked when the caption is clicked while it offers to start. */
|
||||
onStart: (() => void) | null = null;
|
||||
private startable = false;
|
||||
readonly fullscreenButton = new FullscreenCorner(this);
|
||||
|
||||
constructor(source: ViewSource) {
|
||||
super(source);
|
||||
@@ -35,6 +37,7 @@ export class GameScreen extends WorldViewport {
|
||||
text.anchor.set(0.5);
|
||||
this.addChild(text);
|
||||
}
|
||||
this.addChild(this.fullscreenButton);
|
||||
routePointer(
|
||||
this,
|
||||
() => this.running,
|
||||
@@ -59,6 +62,7 @@ export class GameScreen extends WorldViewport {
|
||||
/** null = not running. */
|
||||
setWorld(world: World | null): void {
|
||||
this.running = world;
|
||||
this.fullscreenButton.sync(true, world !== null);
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
@@ -101,5 +105,6 @@ export class GameScreen extends WorldViewport {
|
||||
this.caption.position.set(this.w / 2, this.h / 2);
|
||||
this.hint.visible = this.running !== null && view === null;
|
||||
this.hint.position.set(this.w / 2, this.h / 2);
|
||||
this.fullscreenButton.place(this.w);
|
||||
}
|
||||
}
|
||||
@@ -13,5 +13,14 @@ export function installPlayerHook(screen: GameScreen, player: () => Player | nul
|
||||
screen: () => screen.info(),
|
||||
log: () => player()?.log() ?? [],
|
||||
pixelAt: (x: number, y: number) => stagePixel(ui().app, x, y),
|
||||
/** Whether the page is in fullscreen, and the corner button while it shows (#267). */
|
||||
fullscreen: () => {
|
||||
const button = screen.fullscreenButton;
|
||||
const origin = button.getGlobalPosition();
|
||||
return {
|
||||
on: document.fullscreenElement !== null,
|
||||
button: button.visible ? { x: origin.x + button.w / 2, y: origin.y + button.h / 2 } : null,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user