From 5183a9b0b3b09d03b3645adb66c348f988a2d18c Mon Sep 17 00:00:00 2001
From: Mnem42 <177770058+Mnem42@users.noreply.github.com>
Date: Fri, 17 Oct 2025 15:49:04 +0100
Subject: [PATCH 1/3] Create zoom.js
---
mods/zoom.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 mods/zoom.js
diff --git a/mods/zoom.js b/mods/zoom.js
new file mode 100644
index 00000000..dc8b2b0d
--- /dev/null
+++ b/mods/zoom.js
@@ -0,0 +1,72 @@
+// IIFE because paranoid
+(() => {
+ let canvas_div = document.getElementById("canvasDiv")
+
+ keybinds["9"] = () => handle_zoom("in")
+ keybinds["0"] = () => handle_zoom("out")
+
+ const controls_table = document.getElementById("controlsTable").lastElementChild
+ controls_table.insertAdjacentHTML("beforeBegin",`
+
+ | Zoom in/out |
+ 9/0
+ |
+ `)
+
+ const zoom_levels = [
+ 0.5,
+ 1,
+ 2,
+ 3,
+ 6,
+ 12
+ ]
+
+ window.zoom_level = 1
+
+ function handle_zoom(direction){
+ switch (direction){
+ case "in":
+ if (!(zoom_level+1 in zoom_levels)) { break; }
+ window.zoom_level += 1
+ break;
+ case "out":
+ if (!(zoom_level-1 in zoom_levels)) { break; }
+ window.zoom_level -= 1
+ break;
+ }
+
+ logMessage(`${zoom_levels[zoom_level]}x`)
+ rescale()
+ }
+
+ function rescale(){
+ const scale = zoom_levels[zoom_level];
+ gameCanvas.style.transform = `scale(${scale})`
+
+ canvas_div.style.overflow = scale > 1 ? "scroll" : "unset"
+ }
+
+ // Redefine to give correct numbers when zoomed
+ window.getMousePos = (canvas, evt) => {
+ if (evt.touches) {
+ evt.preventDefault();
+ evt = evt.touches[0];
+ isMobile = true;
+ }
+ const rect = canvas.getBoundingClientRect();
+
+ let x = (evt.clientX - rect.left) / zoom_levels[window.zoom_level];
+ let y = (evt.clientY - rect.top) / zoom_levels[window.zoom_level];
+
+ x = Math.floor((x / canvas.clientWidth) * (width+1));
+ y = Math.floor((y / canvas.clientHeight) * (height+1));
+
+ return {x:x, y:y};
+ }
+
+ runAfterReset(() => {
+ window.zoom_level = 1
+ rescale()
+ })
+})()
From dc29ee6a685e42b1d1bc9792393a5d86d4fd0563 Mon Sep 17 00:00:00 2001
From: Mnem42 <177770058+Mnem42@users.noreply.github.com>
Date: Fri, 17 Oct 2025 15:55:15 +0100
Subject: [PATCH 2/3] slight keybind change
---
mods/zoom.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mods/zoom.js b/mods/zoom.js
index dc8b2b0d..8c02e817 100644
--- a/mods/zoom.js
+++ b/mods/zoom.js
@@ -2,14 +2,14 @@
(() => {
let canvas_div = document.getElementById("canvasDiv")
- keybinds["9"] = () => handle_zoom("in")
- keybinds["0"] = () => handle_zoom("out")
+ keybinds["0"] = () => handle_zoom("in")
+ keybinds["9"] = () => handle_zoom("out")
const controls_table = document.getElementById("controlsTable").lastElementChild
controls_table.insertAdjacentHTML("beforeBegin",`
| Zoom in/out |
- 9/0
+ | 0/9
|
`)
From 9bbaaa3784ddce396ec8fbb27d42c1e19894a00c Mon Sep 17 00:00:00 2001
From: Mnem42 <177770058+Mnem42@users.noreply.github.com>
Date: Mon, 20 Oct 2025 15:14:56 +0100
Subject: [PATCH 3/3] General UI changes + a proper panning implementation
---
mods/zoom.js | 100 +++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 85 insertions(+), 15 deletions(-)
diff --git a/mods/zoom.js b/mods/zoom.js
index 8c02e817..bd08a89d 100644
--- a/mods/zoom.js
+++ b/mods/zoom.js
@@ -2,16 +2,56 @@
(() => {
let canvas_div = document.getElementById("canvasDiv")
- keybinds["0"] = () => handle_zoom("in")
- keybinds["9"] = () => handle_zoom("out")
+ // Be more granular at higher zoom levels
+ const speed_a = () => zoom_level > 3 ? 5 : 10
+ const speed_b = () => zoom_level > 3 ? 10 : 20
+
+ keybinds["9"] = () => handle_zoom("in")
+ keybinds["0"] = () => handle_zoom("out")
+
+ keybinds["w"] = () => handle_pan("up", speed_a())
+ keybinds["a"] = () => handle_pan("left", speed_a())
+ keybinds["s"] = () => handle_pan("down", speed_a())
+ keybinds["d"] = () => handle_pan("right", speed_a())
+
+ keybinds["W"] = () => handle_pan("up", speed_b())
+ keybinds["A"] = () => handle_pan("left", speed_b())
+ keybinds["S"] = () => handle_pan("down", speed_b())
+ keybinds["D"] = () => handle_pan("right", speed_b())
const controls_table = document.getElementById("controlsTable").lastElementChild
+
controls_table.insertAdjacentHTML("beforeBegin",`
-
- | Zoom in/out |
- 0/9
- |
+
+ | Zoom in/out |
+
+ 9/
+ 0
+ |
+
+
+ | Pan |
+
+ W
+ A
+ S
+ D
+ |
+
+
+ | Pan (fast) |
+
+ Shift +
+ W
+ A
+ S
+ D
+ |
+
`)
+
+ const zoom_data_div = document.createElement("div")
+ document.getElementById("logDiv").appendChild(zoom_data_div)
const zoom_levels = [
0.5,
@@ -23,6 +63,7 @@
]
window.zoom_level = 1
+ window.zoom_panning = [0,0]
function handle_zoom(direction){
switch (direction){
@@ -34,17 +75,46 @@
if (!(zoom_level-1 in zoom_levels)) { break; }
window.zoom_level -= 1
break;
- }
-
- logMessage(`${zoom_levels[zoom_level]}x`)
+ }
rescale()
}
- function rescale(){
- const scale = zoom_levels[zoom_level];
- gameCanvas.style.transform = `scale(${scale})`
+ function handle_pan(direction, speed){
+ switch (direction){
+ case "right":
+ zoom_panning[0] -= speed
+ break;
+ case "left":
+ zoom_panning[0] += speed
+ break;
+ case "up":
+ zoom_panning[1] += speed
+ break;
+ case "down":
+ zoom_panning[1] -= speed
+ break;
+ }
+ rescale()
+ }
- canvas_div.style.overflow = scale > 1 ? "scroll" : "unset"
+ function rescale(){
+ log_info()
+
+ const scale = zoom_levels[zoom_level]
+ const x = zoom_panning[0] * (pixelSize * scale)
+ const y = zoom_panning[1] * (pixelSize * scale)
+
+ gameCanvas.style.transform = `translate(${x}px,${y}px) scale(${scale})`
+ }
+
+ function log_info(){
+ // Values are negated to make them more intuitive
+ const x_pan = (-zoom_panning[0]).toString().padEnd(4)
+ const y_pan = (-zoom_panning[1]).toString().padEnd(4)
+
+ zoom_data_div.innerText = ""
+ zoom_data_div.innerText += `Scale: ${zoom_levels[zoom_level]}x\n`
+ zoom_data_div.innerText += `Pan : ${x_pan}, ${y_pan}`
}
// Redefine to give correct numbers when zoomed
@@ -56,8 +126,8 @@
}
const rect = canvas.getBoundingClientRect();
- let x = (evt.clientX - rect.left) / zoom_levels[window.zoom_level];
- let y = (evt.clientY - rect.top) / zoom_levels[window.zoom_level];
+ let x = (evt.clientX - rect.left) / zoom_levels[zoom_level];
+ let y = (evt.clientY - rect.top) / zoom_levels[zoom_level];
x = Math.floor((x / canvas.clientWidth) * (width+1));
y = Math.floor((y / canvas.clientHeight) * (height+1));