Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--index.html5
-rw-r--r--index.js202
-rw-r--r--style.css38
3 files changed, 216 insertions, 29 deletions
diff --git a/index.html b/index.html
index 309e976..536940d 100644
--- a/index.html
+++ b/index.html
@@ -150,8 +150,8 @@
</defs>
<rect id="background" x="-1" y="-1" width="2287" height="3087" />
- <image id="map2" class="map-scans" href="scans/map2.jpg" width="2284" height="1518" x="2" y="2" />
- <image id="map3" class="map-scans" href="scans/map3.jpg" width="2284" height="1518" x="4" y="1564" />
+ <!-- <image id="map2" class="map-scans" href="scans/map2.jpg" width="2284" height="1518" x="2" y="2" />
+ <image id="map3" class="map-scans" href="scans/map3.jpg" width="2284" height="1518" x="4" y="1564" /> -->
<g id="firing-arcs"></g>
<rect id="map" x="-1" y="-1" width="2287" height="3087" />
<g id="points"></g>
@@ -159,6 +159,7 @@
</svg>
<div id="content">
+ <input type="checkbox" class="visible" checked />
<div>
Set firing arc:
<button type="button" class="set-firing-arc" data-size="small">
diff --git a/index.js b/index.js
index 4845aea..6393721 100644
--- a/index.js
+++ b/index.js
@@ -63,14 +63,17 @@ const svgns = "http://www.w3.org/2000/svg",
svg = document.querySelector('svg'),
map = document.querySelector('rect#map'),
hex = document.getElementById('point'),
- pointsGroup = document.getElementById('points'),
- settingsPanel = document.getElementById('panel');
+ ptGrp = document.getElementById('points'),
+ settingsPanel = document.getElementById('panel'),
+ recordSheetVisibility = document.querySelector('#content input[type="checkbox"].visible');
const { x: VIEWBOX_X, y: VIEWBOX_Y, width: VIEWBOX_WIDTH, height: VIEWBOX_HEIGHT } =
svg.viewBox.baseVal;
-const COLUMN_COUNT = 33,
- ROW_COUNT = 51,
+// const COLUMN_COUNT = 33,
+// ROW_COUNT = 51,
+const COLUMN_COUNT = 20,
+ ROW_COUNT = 20,
HORZ_POINT_DISTANCE = 1.005,
VERT_POINT_DISTANCE = Math.sqrt(3) * HORZ_POINT_DISTANCE / 2,
ALTERNATING_OFFSET = HORZ_POINT_DISTANCE / 2,
@@ -85,9 +88,21 @@ const FIRING_ARC_SIZE = {
'large': Math.atan((21 * HORZ_POINT_DISTANCE) / (6 * VERT_POINT_DISTANCE))
}
-Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => {
+let prevVb = localStorage.getItem('viewBox');
+let recVis = localStorage.getItem('recordsVisibility');
+
+if (prevVb) {
+ svg.setAttributeNS(null, 'viewBox', prevVb);
+}
+
+if (recVis == 'false') {
+ recordSheetVisibility.checked = false;
+}
+
+// Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => {
+[].forEach(fieldset => {
const target = document.getElementById(fieldset.name);
- const transform = window.getComputedStyle(target).transform.match(/-?\d+\.?\d*/g);
+ const transform = getComputedStyle(target).transform.match(/-?\d+\.?\d*/g);
const inputs = fieldset.querySelectorAll('input');
if (transform) {
@@ -131,9 +146,12 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
cy = y * 3 / 2 * CIRCUMRADIUS,
point = document.createElementNS(svgns, 'use');
+ cx = parseFloat(cx.toFixed(1));
+ cy = parseFloat(cy.toFixed(1));
+
point.setAttributeNS(null, 'href', `#point`);
- point.setAttributeNS(null, 'x', `${parseFloat(cx.toFixed(1))}`);
- point.setAttributeNS(null, 'y', `${parseFloat(cy.toFixed(1))}`);
+ point.setAttributeNS(null, 'x', cx);
+ point.setAttributeNS(null, 'y', cy);
point.dataset.x = x;
point.dataset.y = y;
@@ -146,21 +164,20 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
{troopNumber, troopAllegiance} = selectedSoldier.dataset,
selector = troopSelector(troopNumber, troopAllegiance);
- let matrix = window.getComputedStyle(pointsGroup).transform.match(/-?\d+\.?\d*/g),
- svgMatrix = new DOMMatrix(matrix || ''),
+ let transProp = getComputedStyle(ptGrp).transform.match(/-?\d+\.?\d*/g),
+ mtx = new DOMMatrix(transProp || ''),
pt = new DOMPoint(point.x.baseVal.value, point.y.baseVal.value),
- svgP = pt.matrixTransform(svgMatrix);
+ svgP = pt.matrixTransform(mtx);
- counter.setAttributeNS(null, 'cx', `${parseFloat(svgP.x.toFixed(1))}`);
- counter.setAttributeNS(null, 'cy', `${parseFloat(svgP.y.toFixed(1))}`);
+ counter.setAttributeNS(null, 'cx', svgP.x);
+ counter.setAttributeNS(null, 'cy', svgP.y);
counter.setAttributeNS(null, 'r', '0.25in');
counter.dataset.troopNumber = troopNumber;
counter.dataset.troopAllegiance = troopAllegiance;
counter.classList.add('counter');
- text.setAttributeNS(null, 'text-anchor', 'middle');
- text.setAttributeNS(null, 'x', `${svgP.x}`);
- text.setAttributeNS(null, 'y', `${svgP.y}`);
+ text.setAttributeNS(null, 'x', svgP.x);
+ text.setAttributeNS(null, 'y', svgP.y);
text.dataset.troopNumber = troopNumber;
text.dataset.troopAllegiance = troopAllegiance;
text.textContent = troopNumber;
@@ -233,9 +250,146 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
point.addEventListener('mouseout', e => e.target.removeAttribute('class'));
- pointsGroup.appendChild(point);
+ ptGrp.appendChild(point);
+
+ text = document.createElementNS(svgns, 'text'),
+
+ text.setAttributeNS(null, 'x', cx);
+ text.setAttributeNS(null, 'y', cy);
+ text.textContent = `${point.dataset.x},${point.dataset.y}`;
+
+ ptGrp.appendChild(text);
}));
+(function debug() {
+ function drawLine(x1, y1, x2, y2) {
+ let start = ptGrp.querySelector(`[data-x="${x1}"][data-y="${y1}"]`);
+ let end = ptGrp.querySelector(`[data-x="${x2}"][data-y="${y2}"]`);
+ let [startX, startY] = [start.x.baseVal.value, start.y.baseVal.value];
+ let [endX, endY] = [end.x.baseVal.value, end.y.baseVal.value];
+
+ let startP = new DOMPoint(startX, startY);
+ let endP = new DOMPoint(endX, endY);
+
+ let tStart = startP.matrixTransform(mtx);
+ let tEnd = endP.matrixTransform(mtx);
+
+ let line = document.createElementNS(svgns, 'line');
+ line.setAttributeNS(null, 'x1', tStart.x);
+ line.setAttributeNS(null, 'y1', tStart.y);
+ line.setAttributeNS(null, 'x2', tEnd.x);
+ line.setAttributeNS(null, 'y2', tEnd.y);
+ line.classList.add('debug');
+
+ line.setAttributeNS(null, 'stroke', 'green');
+ line.setAttributeNS(null, 'stroke-width', 10);
+ svg.appendChild(line);
+
+ return line;
+ }
+
+ let transProp = getComputedStyle(ptGrp).transform.match(/-?\d+\.?\d*/g),
+ mtx = new DOMMatrix(transProp || ''),
+ circR = (new DOMPoint(0, 3 * CIRCUMRADIUS / 2)).matrixTransform(mtx).y * 2 / 3;
+
+ // let l1 = drawLine(1, 1, 1, 2);
+
+ drawLine(0, 0, 5, 4);
+ // drawLine(1, 1, 1, 3);
+
+ // let pt = l1.getPointAtLength(circR);
+
+ // let c = document.createElementNS(svgns, 'circle');
+ // c.setAttributeNS(null, 'cx', pt.x);
+ // c.setAttributeNS(null, 'cy', pt.y);
+ // c.setAttributeNS(null, 'r', 20);
+ // c.setAttributeNS(null, 'fill', 'red');
+ // c.setAttributeNS(null, 'opacity', '0.2');
+ // svg.appendChild(c);
+})();
+
+function evenr_to_axial(x, y) {
+ return {q: x - (y + (y & 1)) / 2, r: y};
+}
+
+function axial_to_evenr(q, r) {
+ return {x: q + (r + (r & 1)) / 2, y: r};
+}
+
+function axial_distance(q1, r1, q2, r2) {
+ return (Math.abs(q1 - q2) + Math.abs(q1 + r1 - q2 - r2) + Math.abs(r1 - r2)) / 2;
+}
+
+function offset_distance(x1, y1, x2, y2) {
+ let { q: q1, r: r1 } = evenr_to_axial(x1, y1),
+ { q: q2, r: r2 } = evenr_to_axial(x2, y2);
+
+ return axial_distance(q1, r1, q2, r2);
+}
+
+function cube_to_axial(q, r, s) {
+ return { q: q, r: r };
+}
+
+function axial_to_cube(q, r) {
+ return { q: q, r: r, s: -q - r};
+}
+
+function cube_round(q, r, s) {
+ rQ = Math.round(q);
+ rR = Math.round(r);
+ rS = Math.round(s);
+
+ let q_diff = Math.abs(rQ - q),
+ r_diff = Math.abs(rR - r),
+ s_diff = Math.abs(rS - s);
+
+ if (q_diff > r_diff && q_diff > s_diff) {
+ rQ = -rR - rS;
+ } else if (r_diff > s_diff) {
+ rR = -rQ - rS;
+ } else {
+ rS = -rQ - rR;
+ }
+
+ return {q: rQ, r: rR, s: rS};
+}
+
+function axial_round(q, r) {
+ let cube = axial_to_cube(q, r),
+ round = cube_round(cube.q, cube.r, cube.s),
+ axial = cube_to_axial(round.q, round.r, round.s);
+
+ return {q: axial.q, r: axial.r};
+}
+
+function lerp(a, b, t) {
+ return a + (b - a) * t;
+}
+
+function axial_lerp(q1, r1, q2, r2, t) {
+ return { q: lerp(q1, q2, t), r: lerp(r1, r2, t) };
+}
+
+function linedraw(x1, y1, x2, y2) {
+ let axial1 = evenr_to_axial(x1, y1),
+ axial2 = evenr_to_axial(x2, y2),
+ n = offset_distance(x1, y1, x2, y2),
+ results = [];
+
+ for (let i = 0; i <= n; i++) {
+ let lerp = axial_lerp(axial1.q, axial1.r, axial2.q, axial2.r, 1.0 / n * i),
+ round = axial_round(lerp.q, lerp.r),
+ { x, y } = axial_to_evenr(round.q, round.r)
+
+ console.log(x, y);
+
+ results.push([x, y]);
+ }
+
+ return results;
+}
+
map.addEventListener('mousemove', e => {
let boundingRect = e.target.getBoundingClientRect();
let pointerX = e.clientX - boundingRect.left;
@@ -462,7 +616,10 @@ svg.addEventListener('wheel', e => {
// newX = newX < VIEWBOX_X ? VIEWBOX_X : newX;
// newY = newY < VIEWBOX_Y ? VIEWBOX_Y : newY;
- svg.setAttributeNS(null, 'viewBox', `${newX} ${newY} ${newWidth} ${newHeight}`);
+ let vb = `${newX} ${newY} ${newWidth} ${newHeight}`
+
+ localStorage.setItem('viewBox', vb);
+ svg.setAttributeNS(null, 'viewBox', vb);
});
svg.addEventListener('pointerdown', e => {
@@ -493,7 +650,10 @@ svg.addEventListener('pointerdown', e => {
moveX = parseInt(svgStartPt.x - svgMovePt.x + x),
moveY = parseInt(svgStartPt.y - svgMovePt.y + y);
- svg.setAttributeNS(null, 'viewBox', `${moveX} ${moveY} ${width} ${height}`);
+ let vb = `${moveX} ${moveY} ${width} ${height}`;
+
+ localStorage.setItem('viewBox', vb);
+ svg.setAttributeNS(null, 'viewBox', vb);
}
}
@@ -505,4 +665,8 @@ svg.addEventListener('pointerdown', e => {
svg.addEventListener('pointermove', pointerMove);
svg.addEventListener('pointerup', pointerUp);
+});
+
+recordSheetVisibility.addEventListener('input', e => {
+ localStorage.setItem('recordsVisibility', recordSheetVisibility.checked);
}); \ No newline at end of file
diff --git a/style.css b/style.css
index 68e5294..8de53aa 100644
--- a/style.css
+++ b/style.css
@@ -8,14 +8,21 @@ body {
svg {
background-color: darkgray;
flex-basis: 100%;
- /* transform: rotate(-90deg);
- transform-origin: center; */
/* max-height: 50vh; */
/* max-height: 100vw; */
}
svg text {
user-select: none;
+ font-size: 4px;
+ fill: white;
+ stroke: black;
+ stroke-width: 0.2px;
+ font-weight: bold;
+ transform: translateY(6px);
+ font-family: monospace;
+ text-anchor: middle;
+ /* display: none; */
}
div#content {
@@ -27,6 +34,7 @@ div#content {
max-height: 100vh;
flex-direction: column;
/* padding: 2px; */
+ position: relative;
}
#content > div:first-of-type {
@@ -34,6 +42,23 @@ div#content {
border-bottom: 1px solid gray;
}
+#content > div {
+ display: none;
+}
+
+#content input[type="checkbox"].visible {
+ position: absolute;
+ right: 0;
+}
+
+#content:has(input[type="checkbox"].visible:checked) > div {
+ display: block;
+}
+
+#content:has(input[type="checkbox"].visible:checked) div#record-sheet {
+ display: flex;
+}
+
#record-sheet {
/* max-height: 100%; */
overflow-y: auto;
@@ -73,13 +98,14 @@ div#content {
}
svg > defs > #point {
- fill: transparent;
+ fill: teal;
+ fill-opacity: 0.5;
stroke: black;
stroke-width: 0.5px;
}
use[href="#point"] {
- opacity: 0;
+ opacity: 0.2;
}
use[href="#point"].active {
@@ -90,10 +116,6 @@ g#points {
transform: translate(19px, 31px) scale(4);
}
-g#test {
- transform: scale(2);
-}
-
#background {
fill: #bacae3;
}