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) => {