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