Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-04-16 15:47:47 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-04-16 15:47:47 -0700
commit4ffd8eb5c47eb104415c90cdd6e4d791dd64070c (patch)
tree419d53f7baf20d599c3b4c505846782eeac09570 /src/index.js
parent811cf8999fbc7d53098124bd8069f907aa944997 (diff)
WIP
Diffstat (limited to 'src/index.js')
-rw-r--r--src/index.js680
1 files changed, 251 insertions, 429 deletions
diff --git a/src/index.js b/src/index.js
index 9acc373..4a66c76 100644
--- a/src/index.js
+++ b/src/index.js
@@ -171,221 +171,145 @@ const PanZoom = new function () {
};
};
-// const Grid = new function () {
-// let cells;
+class Game {
+ constructor(svg) {
+ this.svg = svg;
-// this.setUp = function (cellList) {
-// cells = cellList;
+ this.setUpSightLine(this);
+ this.setUpCounter(this);
+ this.setUpRecordSheet();
+ this.setUpCells();
+ }
-// cellList.forEach(cell => {
-// cell.addEventListener('click', e => {
-// let { dataset: { x }, parentElement: { dataset: { y }}} = cell;
+ static HORZ_POINT_DISTANCE = 1.005;
+ static VERT_POINT_DISTANCE = Math.sqrt(3) * Game.HORZ_POINT_DISTANCE / 2;
-// console.log(`Cell at index { x: ${x}, y: ${y} } clicked.`);
+ static FIRING_ARC_SIZE = {
+ 'small': Math.atan(Game.HORZ_POINT_DISTANCE / (6 * Game.VERT_POINT_DISTANCE)),
+ 'medium': Math.atan((Game.HORZ_POINT_DISTANCE / 2) / Game.VERT_POINT_DISTANCE),
+ 'large': Math.atan((21 * Game.HORZ_POINT_DISTANCE) / (6 * Game.VERT_POINT_DISTANCE))
+ };
-// console.log(Board.getCellPosition(cell));
+ #positionFiringArc(e) {
+ let activeFiringArc = this.querySelector('polygon.firing-arc.active');
-// if (!Counter.getCounter(cell)) {
-// const counter = Counter.getSelected();
+ // TODO: handle exactly horizontal and vertical lines
-// counter && Counter.place(counter, cell);
-// // SightLine.setSource(cell);
-// }
-// });
+ if (activeFiringArc) {
+ let activeFiringArcOutline = this.querySelector(`#lines polygon[data-troop-number="${activeFiringArc.dataset.troopNumber}"][data-troop-allegiance="${activeFiringArc.dataset.troopAllegiance}"]`),
+ board = this.querySelector('#image-maps'),
+ { width, height } = board.getBBox(),
+ pt = new DOMPoint(e.clientX, e.clientY),
+ { x: pointerX, y: pointerY } = pt.matrixTransform(board.getScreenCTM().inverse()),
+ [maxXpx, maxYpx] = [width, height],
+ { x: x1px, y: y1px } = activeFiringArc.points[0];
-// cell.addEventListener('pointerover', e => {
-// const counter = Counter.getSelected();
+ let [x2px, y2px] = [
+ pointerX / width * maxXpx,
+ pointerY / height * maxYpx
+ ];
-// if (counter && Counter.isOnBoard(counter)) {
-// SightLine.setTarget(e.target.parentElement);
-// }
-// });
-// });
-// };
-
-// this.drawLine = function ({ x: sourceX, y: sourceY }, { x: targetX, y: targetY }) {
-// let lineCoords = linedraw(sourceX, sourceY, targetX, targetY);
-// // lineCoords.shift();
-// // let s = lineCoords.map(([x, y]) => `use[href="#point"][data-x="${x}"][data-y="${y}"]`).join(', ');
-
-// console.log(lineCoords);
-
-// // let list = cells.filter(c => c.dataset.x == )
-
-// // ptGrp.querySelectorAll(s).forEach(p => p.classList.add('active'));
-// };
-// };
-
-// const Counter = new function () {
-// let counters;
-
-// this.setUp = function (list) {
-// counters = list;
-
-// counters.forEach(counter => counter.addEventListener('click', e => {
-// e.stopPropagation();
-
-// const { allegiance: allegiance, number: n } = counter.dataset,
-// al = allegiance.charAt(0).toUpperCase() + allegiance.slice(1);
-
-// if (counter.classList.contains('selected')) {
-// counter.classList.toggle('selected');
-// } else {
-// counters.forEach(c => c.classList.remove('selected'));
-// counter.classList.add('selected');
-
-// if (this.isOnBoard(counter)) {
-// SightLine.setSource(counter.parentElement);
-// } else {
-// SightLine.reset();
-// }
-// }
-// }));
-// };
-
-// this.getCounter = function (cell) {
-// return cell.querySelector('use[href*="#t-"]');
-// };
-
-// this.getSelected = function () {
-// return Array.from(counters).find(c => c.classList.contains('selected'));
-// };
-
-// this.place = function (counter, cell) {
-// counter.removeAttribute('data-x');
-// cell.appendChild(counter);
-// SightLine.setSource(cell);
-// };
-
-// this.isOnBoard = function (counter) {
-// return !counter.hasAttributeNS(null, 'data-x');
-// };
-// };
-
-// const SightLine = new function () {
-// let el, source, target;
-
-// this.set = function (line) {
-// el = line;
-// }
-
-// this.clear = function () {
-// // let sl = grid.querySelector('line.sight-line');
-// // let target = grid.querySelector(`use[href="#point"].sight-line-target`);
-
-// // if (sl) {
-// // sl.remove();
-// // }
-
-// // if (target) {
-// // target.classList.remove('sight-line-target');
-// // }
-
-// // this.clearHexes();
-// };
-
-// this.clearHexes = function () {
-// // ptGrp.querySelectorAll('use[href="#point"].active').forEach(el => el.classList.remove('active'));
-// };
-
-// this.reset = function () {
-// el.setAttributeNS(null, 'x1', 0);
-// el.setAttributeNS(null, 'y1', 0);
-// el.setAttributeNS(null, 'x2', 0);
-// el.setAttributeNS(null, 'y2', 0);
-// };
-
-// this.setSource = function (cell) {
-// source = target = cell;
-// const { x, y } = Board.getCellPosition(cell);
-// el.setAttributeNS(null, 'x1', x);
-// el.setAttributeNS(null, 'y1', y);
-// el.setAttributeNS(null, 'x2', x);
-// el.setAttributeNS(null, 'y2', y);
-// };
-
-// this.setTarget = function (cell) {
-// const targetPos = Board.getCellPosition(cell);
-// el.setAttributeNS(null, 'x2', targetPos.x);
-// el.setAttributeNS(null, 'y2', targetPos.y);
-
-// let sourceCoords = {
-// x: parseInt(source.dataset.x),
-// y: parseInt(source.parentElement.dataset.y)
-// }
-
-// let targetCoords = {
-// x: parseInt(cell.dataset.x),
-// y: parseInt(cell.parentElement.dataset.y)
-// }
-
-// Grid.drawLine(sourceCoords, targetCoords);
-// // console.log('target cell', target, 'source cell', source);
-// };
-
-// this.drawHexes = function (...coords) {
-// // this.clearHexes()
-
-// // info.querySelector('#hex-count').textContent = offset_distance(...coords);
-// // info.style.display = 'block';
-
-// // let lineCoords = linedraw(...coords);
-// // lineCoords.shift();
-// // let s = lineCoords.map(([x, y]) => `use[href="#point"][data-x="${x}"][data-y="${y}"]`).join(', ');
-
-// // ptGrp.querySelectorAll(s).forEach(p => p.classList.add('active'));
-// };
-// };
-
-// const Board = new function () {
-// let board;
-
-// function getCells(svg) {
-// return svg.querySelectorAll('g[data-x]');
-// }
-
-// function getCounters(svg) {
-// return svg.querySelectorAll('use[href*="#t-"]');
-// }
-
-// this.setUp = function (svg) {
-// board = svg.querySelector('.board');
-// Grid.setUp(getCells(svg));
-// Counter.setUp(getCounters(svg));
-// SightLine.set(svg.querySelector('.sight-line'));
-// };
-
-// this.getCellPosition = function (cell) {
-// let pt = new DOMPoint(0, 0);
-
-// let transform = getComputedStyle(cell).transform.match(/-?\d+\.?\d*/g);
-// let mtx = new DOMMatrix(transform);
-// pt = pt.matrixTransform(mtx);
-
-// transform = getComputedStyle(cell.parentElement).transform.match(/-?\d+\.?\d*/g);
-// mtx = new DOMMatrix(transform);
-// pt = pt.matrixTransform(mtx);
-
-// return pt;
-// };
-// };
+ let xDiff = x2px - x1px;
+ let yDiff = y2px - y1px;
+ let angle = calculateAngle(xDiff, yDiff);
-class Game {
- constructor(svg) {
- this.svg = svg;
+ let arcAngle = Game.FIRING_ARC_SIZE[activeFiringArc.dataset.size];
+ let distance = Math.sqrt((x2px - x1px) ** 2 + (y2px - y1px) ** 2);
+ let yDelta = distance * Math.cos(angle) * Math.tan(arcAngle);
+ let xDelta = distance * Math.sin(angle) * Math.tan(arcAngle);
- this.setUpSightLine(this);
- this.setUpCounter(this);
- this.setUpRecordSheet();
- this.setUpCells();
+ let [newY1, newX1] = [y2px + yDelta, x2px + xDelta];
+ let [newY2, newX2] = [y2px - yDelta, x2px - xDelta];
+
+ [newX1, newY1] = edgePoint(x1px, y1px, newX1, newY1, maxXpx, maxYpx);
+ [newX2, newY2] = edgePoint(x1px, y1px, newX2, newY2, maxXpx, maxYpx);
+
+ let oppositeEdgeConditions = [
+ newX1 == 0 && newX2 == maxXpx,
+ newX2 == 0 && newX1 == maxXpx,
+ newY1 == 0 && newY2 == maxYpx,
+ newY2 == 0 && newY1 == maxYpx
+ ]
+
+ let orthogonalEdgeConditions = [
+ (newX1 == 0 || newX1 == maxXpx) && (newY2 == 0 || newY2 == maxYpx),
+ (newX2 == 0 || newX2 == maxXpx) && (newY1 == 0 || newY1 == maxYpx),
+ ]
+
+ let points;
+
+ if (oppositeEdgeConditions.some(e => e)) {
+ let cornerPoints;
+
+ if (xDiff > 0 && yDiff > 0) {
+ if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
+ cornerPoints = [[maxXpx, 0], [maxXpx, maxYpx]];
+ } else {
+ cornerPoints = [[maxXpx, maxYpx], [0, maxYpx]];
+ }
+ } else if (xDiff > 0 && yDiff < 0) {
+ if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
+ cornerPoints = [[maxXpx, 0], [maxXpx, maxYpx]];
+ } else {
+ cornerPoints = [[0, 0], [maxXpx, 0]];
+ }
+
+ } else if (xDiff < 0 && yDiff > 0) {
+ if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
+ cornerPoints = [[0, maxYpx], [0, 0]];
+ } else {
+ cornerPoints = [[maxXpx, maxYpx], [0, maxYpx]];
+ }
+
+ } else {
+ if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
+ cornerPoints = [[0, maxYpx], [0, 0]];
+ } else {
+ cornerPoints = [[0, 0], [maxXpx, 0]];
+ }
+
+ }
+ points = `${x1px},${y1px} ${newX1},${newY1} ${cornerPoints[1]} ${cornerPoints[0]} ${newX2},${newY2}`;
+ } else if (orthogonalEdgeConditions.some(e => e)) {
+ let cornerPoints = [];
+ let cp1, cp2;
+
+ if (newX1 == 0 || newX1 == maxXpx) {
+ cp1 = [newX1, yDiff > 0 ? maxYpx : 0];
+ } else {
+ cp1 = [xDiff > 0 ? maxXpx : 0, newY1];
+ }
+
+ if (newX2 == 0 || newX2 == maxXpx) {
+ cp2 = [newX2, yDiff > 0 ? maxYpx : 0];
+ } else {
+ cp2 = [xDiff > 0 ? maxXpx : 0, newY2];
+ }
+
+ if (cp1[0] == cp2[0] && cp1[1] == cp2[1]) {
+ cornerPoints.push(cp1);
+ } else {
+ cornerPoints.push(cp1);
+ cornerPoints.push([xDiff > 0 ? maxXpx : 0, yDiff > 0 ? maxYpx : 0])
+ cornerPoints.push(cp2);
+ }
+
+ points = `${x1px},${y1px} ${newX1},${newY1} ${cornerPoints.join(' ')} ${newX2},${newY2}`;
+ } else {
+ points = `${x1px},${y1px} ${newX1},${newY1} ${newX2},${newY2}`;
+ }
+
+ activeFiringArcOutline.setAttributeNS(null, 'points', points);
+ activeFiringArc.setAttributeNS(null, 'points', points);
+ }
}
getCells() {
- return svg.querySelectorAll('g[data-x]');
+ return this.svg.querySelectorAll('g[data-x]');
}
getCell(x, y) {
- return svg.querySelector(`g[data-y="${y}"] g[data-x="${x}"]`);
+ return this.svg.querySelector(`g[data-y="${y}"] g[data-x="${x}"]`);
}
getHex(cell) {
@@ -393,35 +317,35 @@ class Game {
}
getCounters() {
- return svg.querySelectorAll(`use[data-allegiance][data-number]:not(.clone)`);
+ return this.svg.querySelectorAll(`use[data-allegiance][data-number]:not(.clone)`);
}
getCounter(al, n) {
- return svg.querySelector(`use[data-allegiance="${al}"][data-number="${n}"]:not(.clone)`);
+ return this.svg.querySelector(`use[data-allegiance="${al}"][data-number="${n}"]:not(.clone)`);
}
getCounterAndClones(al, n) {
- return svg.querySelectorAll(`use[data-allegiance="${al}"][data-number="${n}"]`);
+ return this.svg.querySelectorAll(`use[data-allegiance="${al}"][data-number="${n}"]`);
}
getClones(al, n) {
- return svg.querySelectorAll(`use[data-allegiance="${al}"][data-number="${n}"].clone`);
+ return this.svg.querySelectorAll(`use[data-allegiance="${al}"][data-number="${n}"].clone`);
}
getSelected() {
- return svg.querySelector(`use[data-allegiance][data-number].selected`);
+ return this.svg.querySelector(`use[data-allegiance][data-number].selected`);
}
getSightLine() {
- return svg.querySelector('line.sight-line');
+ return this.svg.querySelector('line.sight-line');
}
getExistingArcs(al, n) {
- return svg.querySelectorAll(`#firing-arcs polygon[data-troop-number="${n}"][data-troop-allegiance="${al}"]`);
+ return this.svg.querySelectorAll(`#firing-arcs polygon[data-troop-number="${n}"][data-troop-allegiance="${al}"]`);
}
getUnclippedFiringArcs() {
- return svg.querySelectorAll('#firing-arcs polygon:not([clip-path])');
+ return this.svg.querySelectorAll('#firing-arcs polygon:not([clip-path])');
}
getGridIndex({ parentElement }) {
@@ -429,11 +353,11 @@ class Game {
}
getBoard() {
- return svg.querySelector('.board');
+ return this.svg.querySelector('.board');
}
getActiveHexes() {
- return svg.querySelectorAll('use[href="#hex"].active');
+ return this.svg.querySelectorAll('use[href="#hex"].active');
}
getCellPosition(cell) {
@@ -495,10 +419,10 @@ class Game {
point.addEventListener('click', e => {
let selectedSoldier = document.querySelector('.soldier-record.selected');
let existingOccupant =
- svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`);
+ this.svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`);
if (selectedSoldier && !existingOccupant) {
- let sl = svg.querySelector('.sight-line');
+ let sl = this.svg.querySelector('.sight-line');
this.Counter.place(selectedSoldier, point);
@@ -507,7 +431,7 @@ class Game {
this.SightLine.clear();
} else {
let { x, y } = this.getCellPosition(point.parentElement),
- target = svg.querySelector(`use[href="#hex"].sight-line-target`),
+ target = this.svg.querySelector(`use[href="#hex"].sight-line-target`),
{ x: x2, y: y2 } = this.getGridIndex(target),
{ x: x1, y: y1 } = this.getGridIndex(point);
@@ -522,7 +446,7 @@ class Game {
group.addEventListener('contextmenu', e => {
e.preventDefault();
- let sl = svg.querySelector('.sight-line');
+ let sl = this.svg.querySelector('.sight-line');
if (sl) {
sl.classList.toggle('active');
@@ -545,7 +469,7 @@ class Game {
if (selected) {
let { troopNumber: tn, troopAllegiance: ta } = selected.dataset,
counter = this.Counter.get(tn, ta),
- sl = svg.querySelector('.sight-line');
+ sl = this.svg.querySelector('.sight-line');
if (counter && (!sl || sl.classList.contains('active'))) {
let sourceCell = counter.parentElement;
@@ -558,7 +482,7 @@ class Game {
});
group.addEventListener('pointerout', e => {
- let sl = svg.querySelector('.sight-line.active');
+ let sl = this.svg.querySelector('.sight-line.active');
if (sl && sl.classList.contains('active')) {
this.SightLine.clear();
@@ -586,7 +510,7 @@ class Game {
.checked;
if (isVisible) {
- svg.querySelector(`#${clipPathId}`).style.display = 'none';
+ svg.svg.querySelector(`#${clipPathId}`).style.display = 'none';
}
el.setAttributeNS(null, 'clip-path', `url(#${clipPathId})`);
@@ -658,14 +582,30 @@ class Game {
points = trace.getAttribute('points').split(' ');
if (`${pos.x},${pos.y}` == points.at(0)) {
- let counter = container.getCounter(troopAllegiance, troopNumber);
+ const counter = container.getCounter(troopAllegiance, troopNumber),
+ lockedSl = container.svg.querySelector('.sight-line:not(.active)');
+
counter.setAttributeNS(null, 'x', 0);
counter.setAttributeNS(null, 'y', 0);
- this.parentElement.appendChild(counter);
+ if (!lockedSl) {
+ container.SightLine.clear();
+ } else {
+ const target = container.svg.querySelector('.sight-line-target').parentElement,
+ x1 = this.parentElement.dataset.x,
+ y1 = this.parentElement.parentElement.dataset.y,
+ x2 = target.dataset.x,
+ y2 = target.parentElement.dataset.y;
+
+ lockedSl.setAttributeNS(null, 'x1', pos.x);
+ lockedSl.setAttributeNS(null, 'y1', pos.y);
+
+ container.SightLine.drawHexes(...[x1, y1, x2, y2].map(n => parseInt(n)));
+ }
+
+ this.parentElement.appendChild(counter);
container.Counter.removeClones(counter);
trace.remove();
- container.SightLine.clear();
} else {
points = points.filter(p => p != `${pos.x},${pos.y}`).join(' ');
trace.setAttributeNS(null, 'points', points);
@@ -677,7 +617,7 @@ class Game {
pointerOver = function () {
let { troopNumber, troopAllegiance } = this.dataset;
- cp = svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`);
+ cp = container.svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`);
if (cp) {
cp.style.display = 'none';
@@ -686,7 +626,7 @@ class Game {
pointerOut = function () {
let { troopNumber, troopAllegiance } = this.dataset;
- cp = svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`);
+ cp = container.svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`);
if (cp) {
let isVisible =
@@ -752,8 +692,8 @@ class Game {
trace = grid.querySelector(traceSelector(troopNumber, troopAllegiance));
if (!trace) {
- Counter.remove(this);
- svg.querySelectorAll(`#firing-arcs ${dataSelector(troopNumber, troopAllegiance)}`).forEach(el => el.remove());
+ container.Counter.remove(this);
+ container.svg.querySelectorAll(`#firing-arcs ${dataSelector(troopNumber, troopAllegiance)}`).forEach(el => el.remove());
}
}
};
@@ -882,7 +822,7 @@ class Game {
this.hasProne = function (troopNumber, troopAllegiance) {
let selector = `g#${troopAllegiance}-${troopNumber} use[href="#counter-prone"]`;
- return !!svg.querySelector(selector);
+ return !!container.svg.querySelector(selector);
};
this.addEventListeners = function (counter) {
@@ -898,7 +838,7 @@ class Game {
setUpSightLine(ptGrp) {
const svgns = "http://www.w3.org/2000/svg",
- grid = svg.querySelector('.board');
+ grid = this.svg.querySelector('.board');
this.SightLine = new function() {
this.clear = function() {
@@ -986,141 +926,101 @@ class Game {
};
}
}
-}
-window.addEventListener('load', () => {
- const svg = document.querySelector('object').contentDocument.querySelector('svg');
-
- window.svg = svg;
- window.G = new Game(svg);
-
- const svgns = "http://www.w3.org/2000/svg",
- ptGrp = svg.querySelector('#points'),
- recordSheetVisibility = document.querySelector('#content input[type="checkbox"].visible');
-
- PanZoom.start(svg);
-
- const HORZ_POINT_DISTANCE = 1.005,
- VERT_POINT_DISTANCE = Math.sqrt(3) * HORZ_POINT_DISTANCE / 2,
- FIRING_ARC_SIZE = {
- 'small': Math.atan(HORZ_POINT_DISTANCE / (6 * VERT_POINT_DISTANCE)),
- 'medium': Math.atan((HORZ_POINT_DISTANCE / 2) / VERT_POINT_DISTANCE),
- 'large': Math.atan((21 * HORZ_POINT_DISTANCE) / (6 * VERT_POINT_DISTANCE))
- };
-
- function positionFiringArc(e) {
- let activeFiringArc = svg.querySelector('polygon.firing-arc.active');
-
- // TODO: handle exactly horizontal and vertical lines
-
- if (activeFiringArc) {
- let activeFiringArcOutline = svg.querySelector(`#lines polygon[data-troop-number="${activeFiringArc.dataset.troopNumber}"][data-troop-allegiance="${activeFiringArc.dataset.troopAllegiance}"]`);
- board = svg.querySelector('#image-maps'),
- { width, height } = board.getBBox(),
- pt = new DOMPoint(e.clientX, e.clientY),
- { x: pointerX, y: pointerY } = pt.matrixTransform(board.getScreenCTM().inverse()),
- [maxXpx, maxYpx] = [width, height],
- { x: x1px, y: y1px } = activeFiringArc.points[0];
-
- let [x2px, y2px] = [
- pointerX / width * maxXpx,
- pointerY / height * maxYpx
- ];
-
- let xDiff = x2px - x1px;
- let yDiff = y2px - y1px;
- let angle = calculateAngle(xDiff, yDiff);
-
- let arcAngle = FIRING_ARC_SIZE[activeFiringArc.dataset.size];
- let distance = Math.sqrt((x2px - x1px) ** 2 + (y2px - y1px) ** 2);
- let yDelta = distance * Math.cos(angle) * Math.tan(arcAngle);
- let xDelta = distance * Math.sin(angle) * Math.tan(arcAngle);
-
- let [newY1, newX1] = [y2px + yDelta, x2px + xDelta];
- let [newY2, newX2] = [y2px - yDelta, x2px - xDelta];
-
- [newX1, newY1] = edgePoint(x1px, y1px, newX1, newY1, maxXpx, maxYpx);
- [newX2, newY2] = edgePoint(x1px, y1px, newX2, newY2, maxXpx, maxYpx);
-
- let oppositeEdgeConditions = [
- newX1 == 0 && newX2 == maxXpx,
- newX2 == 0 && newX1 == maxXpx,
- newY1 == 0 && newY2 == maxYpx,
- newY2 == 0 && newY1 == maxYpx
- ]
-
- let orthogonalEdgeConditions = [
- (newX1 == 0 || newX1 == maxXpx) && (newY2 == 0 || newY2 == maxYpx),
- (newX2 == 0 || newX2 == maxXpx) && (newY1 == 0 || newY1 == maxYpx),
- ]
-
- let points;
-
- if (oppositeEdgeConditions.some(e => e)) {
- let cornerPoints;
+ setFiringArc(selectedSoldier, size) {
+ const { troopNumber, troopAllegiance } = selectedSoldier.dataset,
+ counter = this.Counter.get(troopNumber, troopAllegiance),
+ svgns = "http://www.w3.org/2000/svg";
+
+ let existingArcs = this.svg.querySelectorAll(
+ `#firing-arcs [data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`
+ );
+
+ existingArcs.forEach(el => el.remove());
+
+ if (counter) {
+ let arcLayer = this.svg.querySelector('#shapes');
+ let outlineLayer = this.svg.querySelector('#lines');
+ let arcContainer = this.svg.querySelector('#firing-arcs');
+
+ let { x, y } = this.getCellPosition(counter.parentElement);
+
+ let grid = this.svg.querySelector('.board');
+ const transform = getComputedStyle(grid).transform.match(/-?\d+\.?\d*/g);
+ const pt = new DOMPoint(x, y);
+ const mtx = new DOMMatrix(transform);
+ let tPt = pt.matrixTransform(mtx);
+
+ let pivotPoint = [tPt.x, tPt.y];
+ let firingArc = document.createElementNS(svgns, 'polygon');
+ let firingArcOutline = document.createElementNS(svgns, 'polygon');
+
+ firingArc.classList.add('firing-arc', 'active');
+ firingArc.dataset.troopNumber = troopNumber;
+ firingArc.dataset.troopAllegiance = troopAllegiance;
+ firingArc.dataset.size = size;
+ firingArc.setAttributeNS(null, 'points', `${pivotPoint} ${pivotPoint} ${pivotPoint}`);
+
+ firingArcOutline.dataset.troopNumber = troopNumber;
+ 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', `clip-path-${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 => {
+ this.svg.querySelectorAll('.firing-arc.active').forEach(el => el.classList.remove('active'));
+ grid.removeAttribute('style');
+ this.svg.removeEventListener('mousemove', this.#positionFiringArc);
+ firingArc.removeEventListener('click', firingArcPlacementListener);
+ firingArc.removeEventListener('contextmenu', cancelFiringArcPlacement);
+ };
- if (xDiff > 0 && yDiff > 0) {
- if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
- cornerPoints = [[maxXpx, 0], [maxXpx, maxYpx]];
- } else {
- cornerPoints = [[maxXpx, maxYpx], [0, maxYpx]];
- }
- } else if (xDiff > 0 && yDiff < 0) {
- if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
- cornerPoints = [[maxXpx, 0], [maxXpx, maxYpx]];
- } else {
- cornerPoints = [[0, 0], [maxXpx, 0]];
- }
+ let cancelFiringArcPlacement = e => {
+ e.preventDefault();
- } else if (xDiff < 0 && yDiff > 0) {
- if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
- cornerPoints = [[0, maxYpx], [0, 0]];
- } else {
- cornerPoints = [[maxXpx, maxYpx], [0, maxYpx]];
- }
+ firingArc.removeEventListener('click', firingArcPlacementListener);
+ firingArc.removeEventListener('contextmenu', cancelFiringArcPlacement);
- } else {
- if ((newY1 == 0 && newY2 == maxYpx) || (newY1 == maxYpx && newY2 == 0)) {
- cornerPoints = [[0, maxYpx], [0, 0]];
- } else {
- cornerPoints = [[0, 0], [maxXpx, 0]];
- }
+ let existingArcs = this.svg.querySelectorAll(
+ `#firing-arcs [data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`
+ );
- }
- points = `${x1px},${y1px} ${newX1},${newY1} ${cornerPoints[1]} ${cornerPoints[0]} ${newX2},${newY2}`;
- } else if (orthogonalEdgeConditions.some(e => e)) {
- let cornerPoints = [];
- let cp1, cp2;
+ existingArcs.forEach(el => el.remove());
- if (newX1 == 0 || newX1 == maxXpx) {
- cp1 = [newX1, yDiff > 0 ? maxYpx : 0];
- } else {
- cp1 = [xDiff > 0 ? maxXpx : 0, newY1];
- }
+ grid.removeAttribute('style');
+ this.svg.removeEventListener('mousemove', this.#positionFiringArc);
+ };
- if (newX2 == 0 || newX2 == maxXpx) {
- cp2 = [newX2, yDiff > 0 ? maxYpx : 0];
- } else {
- cp2 = [xDiff > 0 ? maxXpx : 0, newY2];
- }
+ grid.style.pointerEvents = 'none';
+ this.svg.addEventListener('mousemove', this.#positionFiringArc);
+ firingArc.addEventListener('click', firingArcPlacementListener);
+ firingArc.addEventListener('contextmenu', cancelFiringArcPlacement);
+ }
+ }
+}
- if (cp1[0] == cp2[0] && cp1[1] == cp2[1]) {
- cornerPoints.push(cp1);
- } else {
- cornerPoints.push(cp1);
- cornerPoints.push([xDiff > 0 ? maxXpx : 0, yDiff > 0 ? maxYpx : 0])
- cornerPoints.push(cp2);
- }
+window.addEventListener('load', () => {
+ const svg = document.querySelector('object').contentDocument.querySelector('svg'),
+ game = new Game(svg);
- points = `${x1px},${y1px} ${newX1},${newY1} ${cornerPoints.join(' ')} ${newX2},${newY2}`;
- } else {
- points = `${x1px},${y1px} ${newX1},${newY1} ${newX2},${newY2}`;
- }
+ const svgns = "http://www.w3.org/2000/svg",
+ ptGrp = svg.querySelector('#points'),
+ recordSheetVisibility = document.querySelector('#content input[type="checkbox"].visible');
- activeFiringArcOutline.setAttributeNS(null, 'points', points);
- activeFiringArc.setAttributeNS(null, 'points', points);
- }
- }
+ PanZoom.start(svg);
let info = document.getElementById('status');
@@ -1230,85 +1130,7 @@ window.addEventListener('load', () => {
let selectedSoldier = document.querySelector('.soldier-record.selected');
if (selectedSoldier) {
- let { troopNumber, troopAllegiance } = selectedSoldier.dataset,
- counter = Counter.get(troopNumber, troopAllegiance);
-
- let existingArcs = svg.querySelectorAll(
- `#firing-arcs [data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`
- );
-
- existingArcs.forEach(el => el.remove());
-
- if (counter) {
- let arcLayer = svg.querySelector('#shapes');
- let outlineLayer = svg.querySelector('#lines');
- let arcContainer = svg.querySelector('#firing-arcs');
-
- let [x, y] = counter.parentElement.getAttribute('transform').match(/-?\d+\.?\d*/g);
-
- const transform = getComputedStyle(grid).transform.match(/-?\d+\.?\d*/g);
- const pt = new DOMPoint(x, y);
- const mtx = new DOMMatrix(transform);
- let tPt = pt.matrixTransform(mtx);
-
- let pivotPoint = [tPt.x, tPt.y];
- let firingArc = document.createElementNS(svgns, 'polygon');
- let firingArcOutline = document.createElementNS(svgns, 'polygon');
-
- firingArc.classList.add('firing-arc', 'active');
- firingArc.dataset.troopNumber = troopNumber;
- firingArc.dataset.troopAllegiance = troopAllegiance;
- firingArc.dataset.size = e.target.dataset.size;
- firingArc.setAttributeNS(null, 'points', `${pivotPoint} ${pivotPoint} ${pivotPoint}`);
-
- firingArcOutline.dataset.troopNumber = troopNumber;
- 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', `clip-path-${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 => {
- svg.querySelectorAll('.firing-arc.active').forEach(el => el.classList.remove('active'));
- 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 = svg.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);
- firingArc.addEventListener('click', firingArcPlacementListener);
- firingArc.addEventListener('contextmenu', cancelFiringArcPlacement);
- }
+ game.setFiringArc(selectedSoldier, el.dataset.size);
}
}));