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));