diff --git a/inventory/templates/testing.html b/inventory/templates/testing.html index 49adb27..41e03e6 100644 --- a/inventory/templates/testing.html +++ b/inventory/templates/testing.html @@ -7,10 +7,12 @@ } #grid { + {# background-image: linear-gradient(to right, #ccc 1px, transparent 1px), linear-gradient(to bottom, #ccc 1px, transparent 1px); background-size: var(--grid) var(--grid); + #} cursor: crosshair; height: 80vh; width: 100%; @@ -77,12 +79,13 @@
- - - -
@@ -186,9 +188,16 @@ if (savedTool) { setActiveTool(savedTool); } +const savedType = localStorage.getItem('gridType'); +if (savedType) { + setActiveType(savedType); +} + resizeAndSetupCanvas(); window.addEventListener('resize', resizeAndSetupCanvas); +setGrid(); + function getActiveTool() { const checked = document.querySelector('input[name="tool"]:checked'); return checked ? checked.id : 'outline'; @@ -202,6 +211,19 @@ function setActiveTool(toolId) { } } +function getActiveType() { + const checked = document.querySelector('input[name="gridType"]:checked'); + return checked ? checked.id : 'noGrid'; +} + +function setActiveType(typeId) { + const el = document.getElementById(typeId); + if (el) { + el.checked = true; + localStorage.setItem('gridType', typeId); + } +} + function snapToGrid(x, y) { const rect = gridEl.getBoundingClientRect(); const clampedX = Math.min(Math.max(x, rect.left), rect.right); @@ -210,17 +232,31 @@ function snapToGrid(x, y) { const localX = clampedX - rect.left; const localY = clampedY - rect.top; - const maxIx = Math.floor(rect.width / {{ grid_size }}); - const maxIy = Math.floor(rect.height / {{ grid_size }}); + const grid = {{ grid_size }}; + const maxIx = Math.floor(rect.width / grid); + const maxIy = Math.floor(rect.height / grid); - const ix = Math.min(Math.max(Math.round(localX / {{ grid_size }}), 0), maxIx); - const iy = Math.min(Math.max(Math.round(localY / {{ grid_size }}), 0), maxIy); + const ix = Math.min(Math.max(Math.round(localX / grid), 0), maxIx); + const iy = Math.min(Math.max(Math.round(localY / grid), 0), maxIy); + + const type = getActiveType(); + + let snapX = localX; + let snapY = localY; + + if (type === 'fullGrid' || type === 'verticalGrid') { + snapX = ix * grid; + } + + if (type === 'fullGrid' || type === 'horizontalGrid') { + snapY = iy * grid; + } return { ix, iy, - x: ix * {{ grid_size }}, - y: iy * {{ grid_size }} + x: snapX, + y: snapY }; } @@ -344,6 +380,45 @@ function saveShapes() { } catch {} } +function setGrid() { + const gridSize = {{ grid_size }}; + const type = getActiveType(); + + gridEl.style.backgroundImage = ""; + gridEl.style.backgroundSize = ""; + gridEl.style.boxShadow = "none"; + + if (type === 'fullGrid') { + gridEl.style.backgroundImage = + "linear-gradient(to right, #ccc 1px, transparent 1px)," + + "linear-gradient(to bottom, #ccc 1px, transparent 1px)"; + gridEl.style.backgroundSize = `${gridSize}px ${gridSize}px`; + gridEl.style.boxShadow = "inset 0 0 0 1px #ccc"; // full frame + + } else if (type === 'horizontalGrid') { + gridEl.style.backgroundImage = + "linear-gradient(to bottom, #ccc 1px, transparent 1px)"; + gridEl.style.backgroundSize = `100% ${gridSize}px`; + + // left + right borders only + gridEl.style.boxShadow = + "inset 1px 0 0 0 #ccc, inset -1px 0 0 0 #ccc"; + + } else if (type === 'verticalGrid') { + gridEl.style.backgroundImage = + "linear-gradient(to right, #ccc 1px, transparent 1px)"; + gridEl.style.backgroundSize = `${gridSize}px 100%`; + + // top + bottom borders only + gridEl.style.boxShadow = + "inset 0 1px 0 0 #ccc, inset 0 -1px 0 0 #ccc"; + + } else { // noGrid + gridEl.style.boxShadow = "inset 0 0 0 1px #ccc"; + } +} + + document.querySelectorAll('input[name="tool"]').forEach(input => { input.addEventListener('change', () => { if (input.checked) { @@ -352,6 +427,15 @@ document.querySelectorAll('input[name="tool"]').forEach(input => { }); }); +document.querySelectorAll('input[name="gridType"]').forEach(input => { + input.addEventListener('change', () => { + if (input.checked) { + localStorage.setItem('gridType', input.id); + } + setGrid(); + }); +}); + importButtonEl.addEventListener('click', () => importEl.click()); importEl.addEventListener('change', (e) => {