diff --git a/inventory/templates/testing.html b/inventory/templates/testing.html index 27592e7..f23ea05 100644 --- a/inventory/templates/testing.html +++ b/inventory/templates/testing.html @@ -24,6 +24,11 @@ top: 10px; transform: translateX(-50%); z-index: 10000; + max-width: calc(100% - 20px); +} + +#toolBar::-webkit-scrollbar { + height: 8px; } #coords { @@ -43,7 +48,12 @@
+ class="btn-toolbar bg-light position-absolute border border-secondary-subtle rounded start-50 p-1 align-items-center flex-nowrap overflow-auto"> +
+ Grid Size: + +
+
@@ -188,6 +198,10 @@ const exportEl = document.getElementById('export'); const gridEl = document.getElementById('grid'); const importButtonEl = document.getElementById('importButton'); const importEl = document.getElementById('import'); +const gridSizeEl = document.getElementById('gridSize'); + +let gridSize = Number(gridSizeEl.value) || {{ grid_size }}; +let dotSize = Math.floor(Math.max(gridSize * 1.25, 32)); let ctx; let dpr = 1; @@ -214,8 +228,24 @@ window.addEventListener('resize', resizeAndSetupCanvas); setGrid(); +function applyGridSize(newSize) { + const n = Number(newSize); + if (!Number.isFinite(n) || n < 1) return; + + gridSize = n; + document.documentElement.style.setProperty('--grid', `${gridSize}px`); + + dotSize = Math.floor(Math.max(gridSize * 1.25, 32)); + + dotSVGEl.setAttribute('width', dotSize); + dotSVGEl.setAttribute('height', dotSize); + + setGrid(); + resizeAndSetupCanvas(); +} + function pxToGrid(v) { - return v / {{ grid_size }}; + return v / gridSize; } function getActiveTool() { @@ -252,7 +282,7 @@ function snapToGrid(x, y) { const localX = clampedX - rect.left; const localY = clampedY - rect.top; - const grid = {{ grid_size }}; + const grid = gridSize; const maxIx = Math.floor(rect.width / grid); const maxIy = Math.floor(rect.height / grid); @@ -342,7 +372,7 @@ function redrawAll() { function drawShape(shape) { if (!ctx) return; - const toPx = (v) => v * {{ grid_size }}; + const toPx = (v) => v * gridSize; ctx.save(); ctx.strokeStyle = shape.color || '#000000'; @@ -411,11 +441,10 @@ function loadShapes() { function saveShapes() { try { localStorage.setItem('gridShapes', JSON.stringify(shapes)); - } catch {} + } catch { } } function setGrid() { - const gridSize = {{ grid_size }}; const type = getActiveType(); gridEl.style.backgroundImage = ""; @@ -472,6 +501,9 @@ document.querySelectorAll('input[name="gridType"]').forEach(input => { }); }); +gridSizeEl.addEventListener('input', () => applyGridSize(gridSizeEl.value)); +gridSizeEl.addEventListener('change', () => applyGridSize(gridSizeEl.value)); + importButtonEl.addEventListener('click', () => importEl.click()); importEl.addEventListener('change', (e) => { @@ -482,6 +514,12 @@ importEl.addEventListener('change', (e) => { reader.onload = () => { try { const data = JSON.parse(reader.result); + + if (data.gridSize) { + gridSizeEl.value = data.gridSize; + applyGridSize(data.gridSize); + } + const loadedShapes = Array.isArray(data) ? data : data.shapes; if (!Array.isArray(loadedShapes)) return; @@ -498,10 +536,10 @@ importEl.addEventListener('change', (e) => { exportEl.addEventListener('click', () => { const payload = { version: 1, - gridSize: {{ grid_size }}, + gridSize: gridSize, shapes }; - const blob = new Blob([JSON.stringify(payload, null,2)], {type: 'application/json'}); + const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; @@ -543,13 +581,16 @@ document.addEventListener('keydown', (e) => { }); gridEl.addEventListener('pointermove', (e) => { + // Note to certain minds that keep thinking we want to mix grid and pixel coordinates. + // No. No we do not. Pixels are not portable. Stop it. + if (!ctx) return; const { ix, iy, x: snapX, y: snapY } = snapToGrid(e.clientX, e.clientY); - const renderX = snapX - {{ dot_size }} / 2; - const renderY = snapY - {{ dot_size }} / 2; + const renderX = snapX - dotSize / 2; + const renderY = snapY - dotSize / 2; coordsEl.classList.remove('d-none');