Clear sightline when counter moves back along move trace

This commit is contained in:
Catalin Mititiuc 2024-04-03 13:14:23 -07:00
parent 616bdf15d9
commit 24aa825bc6
2 changed files with 125 additions and 68 deletions

View File

@ -226,7 +226,7 @@
<button type="button" class="end-move" data-allegiance="davion">
End Movement
</button>
<button type="button" class="end-turn" data-allegiance="davion">
<button type="button" class="end-turn" data-allegiance="liao">
End Turn
</button>
<br>
@ -290,7 +290,7 @@
<button type="button" class="end-move" data-allegiance="liao">
End Movement
</button>
<button type="button" class="end-turn" data-allegiance="liao">
<button type="button" class="end-turn" data-allegiance="davion">
End Turn
</button>
<br>

187
index.js
View File

@ -357,6 +357,10 @@ const Counter = new function() {
return `use.counter${dataSelector(troopNumber, allegiance)}`;
},
position = function(x, y) {
return `use.counter[data-x="${x}"][data-x="${y}"]`;
},
traceSelector = function(troopNumber, allegiance) {
return `polyline.move-trace${dataSelector(troopNumber, allegiance)}`;
},
@ -433,6 +437,10 @@ const Counter = new function() {
return container.querySelector(`${selector(troopNumber, allegiance)}:not(.clone)`);
};
this.getAt = function(x, y) {
return container.querySelector(`${position(x, y)}:not(.clone)`);
};
this.select = function({ dataset: { troopNumber, troopAllegiance }}) {
this.unSelect();
@ -557,6 +565,41 @@ const Counter = new function() {
};
};
const RecordSheet = new function() {
let clipUnclippedFiringArcs = function() {
let unclipped = document.querySelectorAll('#firing-arcs polygon:not([clip-path])');
unclipped.forEach(el => {
let { troopNumber, troopAllegiance } = el.dataset;
el.setAttributeNS(null, 'clip-path', `url(#${troopAllegiance}-${troopNumber})`);
});
};
this.unSelect = function() {
let selected = this.getSelected();
if (selected) {
selected.classList.remove('selected');
}
clipUnclippedFiringArcs();
Counter.unSelect();
};
this.getSelected = function() {
return document.querySelector('.soldier-record.selected');
};
this.select = function(el) {
let { troopNumber, troopAllegiance } = el.dataset;
this.unSelect();
el.classList.add('selected');
existingArcs = document.querySelectorAll(`#firing-arcs polygon[data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`);
existingArcs.forEach(el => el.removeAttribute('clip-path'));
};
};
POINTS.forEach((row, index) => row.forEach(([x, y]) => {
var cx = x * INRADIUS * 2 + (isEven(index) ? INRADIUS : 0),
cy = y * 3 / 2 * CIRCUMRADIUS,
@ -604,27 +647,17 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
});
point.addEventListener('mouseover', e => {
let selectedSoldier = document.querySelector('.soldier-record.selected');
let selected = RecordSheet.getSelected();
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}"]`);
let counter = Counter.get(tn, ta);
let sl = svg.querySelector('.sight-line');
if (selected) {
let { troopNumber: tn, troopAllegiance: ta } = selected.dataset,
counter = Counter.get(tn, ta),
sl = document.querySelector('line.sight-line');
if (counter && (!sl || sl.classList.contains('active'))) {
if (sl) {
info.querySelector('#hex-count').textContent = '-';
info.style.display = 'none';
ptGrp.querySelectorAll('.active').forEach(el => el.removeAttribute('class'));
svg.querySelectorAll('.sight-line').forEach(el => el.remove());
}
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 source = ptGrp.querySelector(`use[data-x="${counter.dataset.x}"][data-y="${counter.dataset.y}"]`),
[x1, y1] = [source.getAttribute('x'), source.getAttribute('y')],
[x2, y2] = [e.target.getAttribute('x'), e.target.getAttribute('y')];
if (x1 !== x2 || y1 !== y2) {
let { x: svgX1, y: svgY1 } = ptGrpToSvgPt(x1, y1);
@ -676,17 +709,8 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => {
document.querySelectorAll('.soldier-record').forEach(el =>
el.addEventListener('click', e => {
if (el.classList.contains('selected')) {
el.classList.remove('selected');
Counter.unSelect();
} else {
document.querySelectorAll('.soldier-record.selected').forEach(el =>
el.classList.remove('selected')
);
el.classList.add('selected');
RecordSheet.select(el);
Counter.select(el);
}
let sl = svg.querySelector('.sight-line');
@ -699,6 +723,42 @@ document.querySelectorAll('.soldier-record').forEach(el =>
})
);
document.querySelector('#grid').addEventListener('click', e => {
let point = ptGrp.querySelector(`[data-x="${e.target.dataset.x}"][data-y="${e.target.dataset.y}"]`),
sl = svg.querySelector('.sight-line');
if (sl) {
sl.classList.add('active');
point.dispatchEvent(new MouseEvent('mouseout'));
point.dispatchEvent(new MouseEvent('mouseover'));
}
});
document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', e => {
let selected = RecordSheet.getSelected();
if (selected) {
Counter.endMove(selected);
RecordSheet.unSelect();
selected.classList.toggle('movement-ended');
}
}));
document.querySelectorAll('.end-turn').forEach(el =>
el.addEventListener('click', ({ target: { dataset: { allegiance }}}) => {
let dataSelector = `[data-troop-allegiance="${allegiance}"]`,
records = Array.from(qA(`.soldier-record${dataSelector}`));
qA(`#firing-arcs ${dataSelector}`).forEach(el => el.remove());
records
.sort((el1, el2) => el1.dataset.troopNumber > el2.dataset.troopNumber)
.forEach(el => el.classList.remove('movement-ended'));
RecordSheet.select(records.at(0));
})
);
document.querySelectorAll('.set-firing-arc').forEach(el => el.addEventListener('click', e => {
let selectedSoldier = document.querySelector('.soldier-record.selected');
@ -715,6 +775,7 @@ document.querySelectorAll('.set-firing-arc').forEach(el => el.addEventListener('
if (counter) {
let arcLayer = document.getElementById('shapes');
let outlineLayer = document.getElementById('lines');
let arcContainer = document.getElementById('firing-arcs');
let grid = document.getElementById('grid');
const transform = getComputedStyle(grid).transform.match(/-?\d+\.?\d*/g);
@ -736,19 +797,49 @@ document.querySelectorAll('.set-firing-arc').forEach(el => el.addEventListener('
firingArcOutline.dataset.troopAllegiance = troopAllegiance;
firingArcOutline.setAttributeNS(null, 'points', `${pivotPoint} ${pivotPoint} ${pivotPoint}`);
let clipShape = document.createElementNS(svgns, 'circle');
clipShape.setAttributeNS(null, 'cx', tPt.x);
clipShape.setAttributeNS(null, 'cy', tPt.y);
clipShape.setAttributeNS(null, 'r', 100);
let clipPath = document.createElementNS(svgns, 'clipPath');
clipPath.setAttributeNS(null, 'id', `${troopAllegiance}-${troopNumber}`);
clipPath.dataset.troopNumber = troopNumber;
clipPath.dataset.troopAllegiance = troopAllegiance;
clipPath.appendChild(clipShape);
arcContainer.appendChild(clipPath);
arcLayer.appendChild(firingArc);
outlineLayer.appendChild(firingArcOutline);
let firingArcPlacementListener = e => {
document.querySelectorAll('.firing-arc.active').forEach(el => el.classList.remove('active'));
ptGrp.style.pointerEvents = '';
svg.removeEventListener('click', firingArcPlacementListener);
ptGrp.removeAttribute('style');
svg.removeEventListener('mousemove', positionFiringArc);
firingArc.removeEventListener('click', firingArcPlacementListener);
firingArc.removeEventListener('contextmenu', cancelFiringArcPlacement);
};
let cancelFiringArcPlacement = e => {
e.preventDefault();
firingArc.removeEventListener('click', firingArcPlacementListener);
firingArc.removeEventListener('contextmenu', cancelFiringArcPlacement);
let existingArcs = document.querySelectorAll(
`#firing-arcs [data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`
);
existingArcs.forEach(el => el.remove());
ptGrp.removeAttribute('style');
svg.removeEventListener('mousemove', positionFiringArc);
};
ptGrp.style.pointerEvents = 'none';
svg.addEventListener('mousemove', positionFiringArc);
svg.addEventListener('click', firingArcPlacementListener);
firingArc.addEventListener('click', firingArcPlacementListener);
firingArc.addEventListener('contextmenu', cancelFiringArcPlacement);
}
}
}));
@ -831,40 +922,6 @@ recordSheetVisibility.addEventListener('input', e => {
localStorage.setItem('recordsVisibility', recordSheetVisibility.checked);
});
document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', e => {
let selectedSoldier = document.querySelector('.soldier-record.selected');
if (selectedSoldier) {
Counter.endMove(selectedSoldier);
selectedSoldier.classList.toggle('selected');
selectedSoldier.classList.toggle('movement-ended');
}
}));
let endTurnButtons = document.querySelectorAll('.end-turn');
let [al1, al2] = Array.from(endTurnButtons).map(el => el.dataset.allegiance);
endTurnButtons.forEach(el =>
el.addEventListener('click', ({target: {dataset: {allegiance}}}) => {
let al = allegiance == al1 ? al2 : al1;
qA(`#firing-arcs [data-troop-allegiance="${al}"]`).forEach(el => el.remove());
qA(`.soldier-record[data-troop-allegiance="${al}"]`).forEach(el =>
el.classList.remove('movement-ended')
);
let selected = q(`.soldier-record.selected`);
if (selected) {
selected.classList.remove('selected');
}
q(`.soldier-record[data-troop-allegiance="${al}"]`).classList.add('selected');
})
);
(function debug() {
function drawLine(x1, y1, x2, y2) {
let start = ptGrp.querySelector(`[data-x="${x1}"][data-y="${y1}"]`);