WIP: sight line and hex count

This commit is contained in:
Catalin Constantin Mititiuc 2025-06-16 22:41:28 -07:00
parent 819fef2e67
commit d438469e33
3 changed files with 90 additions and 28 deletions

View File

@ -101,7 +101,7 @@
</p>
</template>
<div id="panel">
<div id="debug">
<fieldset name="point">
<legend>hex</legend>
<div>
@ -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>

View File

@ -70,10 +70,10 @@ const svgns = "http://www.w3.org/2000/svg",
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 = 20,
ROW_COUNT = 20,
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,
@ -141,6 +141,15 @@ if (recVis == 'false') {
});
});
function ptGrpToSvgPt(x, y) {
let transProp = getComputedStyle(ptGrp).transform.match(/-?\d+\.?\d*/g),
mtx = new DOMMatrix(transProp || ''),
pt = new DOMPoint(x, y),
svgP = pt.matrixTransform(mtx);
return svgP;
}
POINTS.forEach((row, index) => row.forEach(([x, y]) => {
var cx = x * INRADIUS * 2 + (isEven(index) ? INRADIUS : 0),
cy = y * 3 / 2 * CIRCUMRADIUS,
@ -174,6 +183,8 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
counter.setAttributeNS(null, 'r', '0.25in');
counter.dataset.troopNumber = troopNumber;
counter.dataset.troopAllegiance = troopAllegiance;
counter.dataset.x = point.dataset.x;
counter.dataset.y = point.dataset.y;
counter.classList.add('counter');
text.setAttributeNS(null, 'x', svgP.x);
@ -235,8 +246,8 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
document.querySelectorAll('.sight-line').forEach(el => el.remove());
});
svg.appendChild(counter);
svg.appendChild(text);
svg.insertBefore(counter, ptGrp);
svg.insertBefore(text, ptGrp);
}
});
@ -245,20 +256,58 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
if (selectedSoldier) {
e.target.classList.add('active');
let { troopNumber: tn, troopAllegiance: ta } = selectedSoldier.dataset;
let counter = svg.querySelector(`circle.counter[data-troop-number="${tn}"][data-troop-allegiance="${ta}"]`);
if (counter) {
let source = ptGrp.querySelector(`use[data-x="${counter.dataset.x}"][data-y="${counter.dataset.y}"]`);
let [x1, y1] = [source.x.baseVal.value, source.y.baseVal.value];
let [x2, y2] = [e.target.x.baseVal.value, e.target.y.baseVal.value];
let { x: svgX1, y: svgY1 } = ptGrpToSvgPt(x1, y1);
let { x: svgX2, y: svgY2 } = ptGrpToSvgPt(x2, y2);
let sightLine = document.createElementNS(svgns, 'line');
sightLine.classList.add('sight-line');
sightLine.setAttributeNS(null, 'x1', svgX1);
sightLine.setAttributeNS(null, 'y1', svgY1);
sightLine.setAttributeNS(null, 'x2', svgX2);
sightLine.setAttributeNS(null, 'y2', svgY2);
svg.appendChild(sightLine);
let coords = [
counter.dataset.x,
counter.dataset.y,
e.target.dataset.x,
e.target.dataset.y
].map(n => parseInt(n));
console.log(offset_distance(...coords))
let lineCoords = linedraw(...coords);
lineCoords.shift();
let s = lineCoords.map(([x, y]) => `use[data-x="${x}"][data-y="${y}"]`).join(', ');
ptGrp.querySelectorAll(s).forEach(p => p.classList.add('active'));
}
}
});
point.addEventListener('mouseout', e => e.target.removeAttribute('class'));
point.addEventListener('mouseout', e => {
ptGrp.querySelectorAll('.active').forEach(el => el.removeAttribute('class'));
svg.querySelectorAll('.sight-line').forEach(el => el.remove());
});
ptGrp.appendChild(point);
text = document.createElementNS(svgns, 'text'),
// text = document.createElementNS(svgns, 'text'),
text.setAttributeNS(null, 'x', cx);
text.setAttributeNS(null, 'y', cy);
text.textContent = `${point.dataset.x},${point.dataset.y}`;
// text.setAttributeNS(null, 'x', cx);
// text.setAttributeNS(null, 'y', cy);
// text.textContent = `${point.dataset.x},${point.dataset.y}`;
ptGrp.appendChild(text);
// ptGrp.appendChild(text);
}));
(function debug() {
@ -281,8 +330,8 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
line.setAttributeNS(null, 'y2', tEnd.y);
line.classList.add('debug');
line.setAttributeNS(null, 'stroke', 'green');
line.setAttributeNS(null, 'stroke-width', 10);
line.setAttributeNS(null, 'stroke', 'gold');
line.setAttributeNS(null, 'stroke-width', 2);
svg.appendChild(line);
return line;
@ -294,8 +343,22 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
// let l1 = drawLine(1, 1, 1, 2);
drawLine(0, 0, 5, 4);
// drawLine(1, 1, 1, 3);
// drawLine(0, 0, 5, 4);
// let coords = [0, 0, 14, 9];
// drawLine(...coords);
// linedraw(0, 0, 14, 9).forEach(([x, y]) => {
// document.querySelector(`[data-x="${x}"][data-y="${y}"]`).style.opacity = 1;
// });
// linedraw(0, 4, 14, 13).forEach(([x, y]) => {
// linedraw(14, 13, 0, 4).forEach(([x, y]) => {
// document.querySelector(`[data-x="${x}"][data-y="${y}"]`).style.opacity = 1;
// });
// linedraw(14, 9, 0, 0).forEach(([x, y]) => {
// document.querySelector(`[data-x="${x}"][data-y="${y}"]`).style.opacity = 1;
// });
// let pt = l1.getPointAtLength(circR);
@ -382,8 +445,6 @@ function linedraw(x1, y1, x2, y2) {
round = axial_round(lerp.q, lerp.r),
{ x, y } = axial_to_evenr(round.q, round.r)
console.log(x, y);
results.push([x, y]);
}
@ -510,6 +571,7 @@ document.querySelectorAll('.soldier-record').forEach(el =>
document.querySelectorAll('.soldier-record.selected').forEach(el =>
el.classList.remove('selected')
);
el.classList.add('selected');
}
})

View File

@ -15,8 +15,8 @@ svg {
svg text {
user-select: none;
font-size: 4px;
fill: white;
stroke: black;
fill: black;
/* stroke: black; */
stroke-width: 0.2px;
font-weight: bold;
transform: translateY(6px);
@ -99,13 +99,13 @@ div#content {
svg > defs > #point {
fill: teal;
fill-opacity: 0.5;
fill-opacity: 0.2;
stroke: black;
stroke-width: 0.5px;
}
use[href="#point"] {
opacity: 0.2;
opacity: 0;
}
use[href="#point"].active {
@ -133,7 +133,7 @@ image.map-scans {
/* opacity: 0.33; */
}
#panel {
#debug {
display: none;
position: absolute;
right: 0;
@ -142,7 +142,7 @@ image.map-scans {
padding: 2px;
}
#panel fieldset label {
#debug fieldset label {
display: block;
text-align: right;
}
@ -198,7 +198,7 @@ line.firing-arc {
}
.sight-line {
stroke: black;
stroke: orangered;
stroke-width: 3px;
}