add ZoomMouseScene with zoom-to-mouse correction

Implements scroll correction after cam.setZoom() so the world point
under the mouse stays fixed. Formula accounts for Phaser's
center-based zoom: scrollX += (mouseX - cw/2) * (1/zBefore - 1/zAfter).
Tab switches between the two test scenes in both directions.
Also fixes centerWorld formula in ZoomTestScene overlay and logs.
This commit is contained in:
2026-03-21 11:49:39 +00:00
parent d83b97a447
commit 7f0ef0554e
3 changed files with 379 additions and 6 deletions

View File

@@ -31,6 +31,7 @@ export class ZoomTestScene extends Phaser.Scene {
s: Phaser.Input.Keyboard.Key
a: Phaser.Input.Keyboard.Key
d: Phaser.Input.Keyboard.Key
tab: Phaser.Input.Keyboard.Key
}
private snapshotTimer = 0
@@ -136,8 +137,14 @@ export class ZoomTestScene extends Phaser.Scene {
s: kb.addKey(Phaser.Input.Keyboard.KeyCodes.S),
a: kb.addKey(Phaser.Input.Keyboard.KeyCodes.A),
d: kb.addKey(Phaser.Input.Keyboard.KeyCodes.D),
tab: kb.addKey(Phaser.Input.Keyboard.KeyCodes.TAB),
}
;(this.keys.tab as unknown as { preventDefault: boolean }).preventDefault = true
this.keys.tab.on('down', () => {
this.scene.start('ZoomMouse')
})
this.input.on('wheel', (
ptr: Phaser.Input.Pointer,
_objs: unknown,
@@ -264,8 +271,9 @@ export class ZoomTestScene extends Phaser.Scene {
const vpHeightPx = cam.height / cam.zoom
const vpWidthTiles = vpWidthPx / TILE_SIZE
const vpHeightTiles = vpHeightPx / TILE_SIZE
const centerWorldX = cam.scrollX + vpWidthPx / 2
const centerWorldY = cam.scrollY + vpHeightPx / 2
// Phaser zooms from screen center: visual center = scrollX + screenWidth/2
const centerWorldX = cam.scrollX + cam.width / 2
const centerWorldY = cam.scrollY + cam.height / 2
const mouseTileX = Math.floor(ptr.worldX / TILE_SIZE)
const mouseTileY = Math.floor(ptr.worldY / TILE_SIZE)
const centerTileX = Math.floor(centerWorldX / TILE_SIZE)
@@ -294,7 +302,7 @@ export class ZoomTestScene extends Phaser.Scene {
`roundPixels: ${(this.game.renderer.config as Record<string, unknown>)['roundPixels']}`,
`Renderer: ${renderer}`,
'',
'[Scroll] Zoom [WASD / ↑↓←→] Pan',
'[Scroll] Zoom [WASD / ↑↓←→] Pan [Tab] → Mouse',
]
this.logText.setText(lines)
@@ -317,8 +325,8 @@ export class ZoomTestScene extends Phaser.Scene {
vpWorld: { w: +vpW.toFixed(2), h: +vpH.toFixed(2) },
vpTiles: { w: +((vpW / TILE_SIZE).toFixed(3)), h: +((vpH / TILE_SIZE).toFixed(3)) },
centerWorld: {
x: +(cam.scrollX + vpW / 2).toFixed(2),
y: +(cam.scrollY + vpH / 2).toFixed(2),
x: +(cam.scrollX + cam.width / 2).toFixed(2),
y: +(cam.scrollY + cam.height / 2).toFixed(2),
},
mouse: {
screen: { x: +ptr.x.toFixed(1), y: +ptr.y.toFixed(1) },