Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/game/counter.js')
-rw-r--r--src/modules/game/counter.js148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/modules/game/counter.js b/src/modules/game/counter.js
new file mode 100644
index 0000000..69552d8
--- /dev/null
+++ b/src/modules/game/counter.js
@@ -0,0 +1,148 @@
+const svgns = "http://www.w3.org/2000/svg";
+
+export default class Counter {
+ constructor(svg) {
+ this.svg = svg;
+ this.selectedClass = 'selected';
+ }
+
+ dataSelector({ dataset: { allegiance, number }}) {
+ return `[data-number="${number}"][data-allegiance="${allegiance}"]`;
+ }
+
+ position(x, y) {
+ return `g[data-x="${x}"][data-y="${y}"]`;
+ }
+
+ counterPosition(x, y) {
+ return `.counter[data-x="${x}"][data-x="${y}"]`;
+ }
+
+ traceSelector(counter) {
+ return `polyline.move-trace${this.dataSelector(counter)}`;
+ }
+
+ getClones(counter) {
+ return this.svg.querySelectorAll(`.counter.clone${this.dataSelector(counter)}`);
+ }
+
+ getCounter(selected) {
+ return this.svg.querySelector(`.counter${this.dataSelector(selected)}:not(.clone)`);
+ }
+
+ getCounterAndClones(counter) {
+ return this.svg.querySelectorAll(`.counter${this.dataSelector(counter)}`);
+ }
+
+ getTrace(counter) {
+ return this.svg.querySelector(this.traceSelector(counter));
+ }
+
+ getCellPosition(cell) {
+ let pt = new DOMPoint(0, 0),
+ transform = getComputedStyle(cell).transform.match(/-?\d+\.?\d*/g),
+ 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;
+ }
+
+ getBoard() {
+ return this.svg.querySelector('.board');
+ }
+
+ place(selected, cell) {
+ let points,
+ counterNodeList = this.getCounterAndClones(selected);
+
+ if (counterNodeList.length > 0 && selected.parentElement.hasAttribute('data-x')) {
+ let trace = this.svg.querySelector(this.traceSelector(selected));
+
+ let prevCoords = [
+ selected.parentElement.dataset.x,
+ selected.parentElement.parentElement.dataset.y
+ ]
+
+ let clone = selected.cloneNode(true);
+ clone.classList.remove(this.selectedClass);
+ clone.classList.add('clone');
+
+ selected.dataset.previous = prevCoords;
+ selected.parentElement.appendChild(clone);
+ cell.appendChild(selected);
+
+ selected.childNodes.forEach(n => {
+ if (n.classList.contains('removed')) {
+ n.remove();
+ } else if ('preexisting' in n.dataset) {
+ delete n.dataset.preexisting;
+ }
+ });
+
+ let previous = this.getCellPosition(clone.parentElement),
+ current = this.getCellPosition(selected.parentElement);
+
+ if (!trace) {
+ trace = document.createElementNS(svgns, 'polyline');
+
+ points = `${previous.x},${previous.y} ${current.x},${current.y}`;
+
+ trace.dataset.number = selected.dataset.number;
+ trace.dataset.allegiance = selected.dataset.allegiance;
+ trace.classList.add('move-trace');
+
+ this.getBoard().prepend(trace);
+ } else {
+ points = `${trace.getAttribute('points')} ${current.x},${current.y}`;
+ }
+
+ trace.setAttributeNS(null, 'points', points);
+ } else {
+ selected.removeAttribute('data-x');
+ cell.appendChild(selected);
+ }
+ }
+
+ removeClones(counter) {
+ this.getClones(counter).forEach(c => c.remove());
+ }
+
+ endMove(counter) {
+ const trace = this.svg.querySelector(this.traceSelector(counter)),
+ proneCounter = counter.querySelector('[href="#counter-prone"]');
+
+ if (trace) {
+ trace.remove();
+ }
+
+ delete counter.dataset.previous;
+
+ if (proneCounter) {
+ proneCounter.dataset.preexisting = '';
+ }
+
+ this.removeClones(counter);
+ }
+
+ hasProne(counter) {
+ return !!counter.querySelector('[href="#counter-prone"]');
+ }
+
+ toggleProne(counter) {
+ let proneCounter = counter.querySelector('[href="#counter-prone"]');
+
+ if (!proneCounter) {
+ proneCounter = document.createElementNS(svgns, 'use');
+ proneCounter.setAttributeNS(null, 'href', '#counter-prone');
+ counter.appendChild(proneCounter);
+ } else if ('preexisting' in proneCounter.dataset) {
+ proneCounter.classList.toggle('removed');
+ } else {
+ proneCounter.remove();
+ }
+ }
+}