diff --git a/src/systems/CameraSystem.ts b/src/systems/CameraSystem.ts index ca995ef..7d507fd 100644 --- a/src/systems/CameraSystem.ts +++ b/src/systems/CameraSystem.ts @@ -26,6 +26,10 @@ export class CameraSystem { private middlePanActive = false private lastPanX = 0 private lastPanY = 0 + private mouseScreenX = 0 + private mouseScreenY = 0 + private mouseWorldX = 0 + private mouseWorldY = 0 private debugCross?: Phaser.GameObjects.Graphics constructor(scene: Phaser.Scene, adapter: LocalAdapter) { @@ -62,18 +66,24 @@ export class CameraSystem { this.debugCross.lineBetween(cx - 12, cy, cx + 12, cy) this.debugCross.lineBetween(cx, cy - 12, cx, cy + 12) + // Track mouse world position on every move so we have a stable value for zoom + this.scene.input.on('pointermove', (ptr: Phaser.Input.Pointer) => { + this.mouseScreenX = ptr.x + this.mouseScreenY = ptr.y + this.mouseWorldX = cam.scrollX + ptr.x / cam.zoom + this.mouseWorldY = cam.scrollY + ptr.y / cam.zoom + }) + // Scroll wheel zoom — zoom toward mouse pointer - this.scene.input.on('wheel', (ptr: Phaser.Input.Pointer, _objs: unknown, _dx: number, dy: number) => { + this.scene.input.on('wheel', (_ptr: Phaser.Input.Pointer, _objs: unknown, _dx: number, dy: number) => { const newZoom = Phaser.Math.Clamp(cam.zoom - Math.sign(dy) * ZOOM_STEP, MIN_ZOOM, MAX_ZOOM) if (newZoom === cam.zoom) return - const worldX = ptr.worldX // capture BEFORE zoom changes the value - const worldY = ptr.worldY cam.setZoom(newZoom) - cam.scrollX = worldX - ptr.x / newZoom - cam.scrollY = worldY - ptr.y / newZoom + cam.scrollX = this.mouseWorldX - this.mouseScreenX / newZoom + cam.scrollY = this.mouseWorldY - this.mouseScreenY / newZoom const centerX = cam.scrollX + cam.width / (2 * cam.zoom) const centerY = cam.scrollY + cam.height / (2 * cam.zoom) - console.log(`[zoom] ptr=(${ptr.x.toFixed(0)},${ptr.y.toFixed(0)}) world=(${ptr.worldX.toFixed(0)},${ptr.worldY.toFixed(0)}) center=(${centerX.toFixed(0)},${centerY.toFixed(0)}) zoom=${cam.zoom.toFixed(2)}`) + console.log(`[zoom] screen=(${this.mouseScreenX.toFixed(0)},${this.mouseScreenY.toFixed(0)}) world=(${this.mouseWorldX.toFixed(0)},${this.mouseWorldY.toFixed(0)}) center=(${centerX.toFixed(0)},${centerY.toFixed(0)}) zoom=${cam.zoom.toFixed(2)}`) }) // Middle-click pan: start on button down