Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'index.js')
-rw-r--r--index.js189
1 files changed, 123 insertions, 66 deletions
diff --git a/index.js b/index.js
index d78d4b2..df7d3e7 100644
--- a/index.js
+++ b/index.js
@@ -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');
- Counter.select(el);
- }
+ 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}"]`);