WIP: handle clicking on counters at the cell level

This commit is contained in:
Catalin Constantin Mititiuc 2024-04-23 19:01:29 -07:00
parent 1a75bf469a
commit f60969ef8d
2 changed files with 121 additions and 59 deletions

View File

@ -6,8 +6,6 @@ export default class Counter {
constructor(svg, container) { constructor(svg, container) {
this.svg = svg; this.svg = svg;
this.container = container; this.container = container;
this.getCounters().forEach(c => this.addEventListeners(c));
} }
dataSelector(troopNumber, allegiance) { dataSelector(troopNumber, allegiance) {
@ -60,13 +58,6 @@ export default class Counter {
return pt; return pt;
} }
addEventListeners(counter) {
counter.addEventListener('pointerover', this.pointerOver.bind(this));
counter.addEventListener('pointerout', this.pointerOut.bind(this));
counter.addEventListener('click', this.click.bind(this));
// counter.addEventListener('dblclick', dblClick);
}
pointerOver(e) { pointerOver(e) {
const { number: troopNumber, allegiance: troopAllegiance } = e.target.dataset, const { number: troopNumber, allegiance: troopAllegiance } = e.target.dataset,
cp = this.svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`); cp = this.svg.querySelector(`#clip-path-${troopAllegiance}-${troopNumber}`);
@ -245,32 +236,33 @@ export default class Counter {
troopAllegiance = selected.dataset.allegiance, troopAllegiance = selected.dataset.allegiance,
troopNumber = selected.dataset.number; troopNumber = selected.dataset.number;
let counter, points, let points,
counterNodeList = this.getCounterAndClones(troopAllegiance, troopNumber); counterNodeList = this.getCounterAndClones(troopAllegiance, troopNumber);
if (counterNodeList.length > 0 && selected.parentElement.hasAttribute('data-x')) { if (counterNodeList.length > 0 && selected.parentElement.hasAttribute('data-x')) {
let counters = Array.from(counterNodeList), let trace = this.svg.querySelector(this.traceSelector(troopNumber, troopAllegiance));
original = counters.find(el => !el.classList.contains('clone')),
trace = this.svg.querySelector(this.traceSelector(troopNumber, troopAllegiance));
counter = original.cloneNode(); let prevCoords = [
counter.setAttributeNS(null, 'x', 0); selected.parentElement.dataset.x,
counter.setAttributeNS(null, 'y', 0); selected.parentElement.parentElement.dataset.y
counter.classList.remove(selectedClass); ]
counter.classList.add('clone');
original.setAttributeNS(null, 'x', 0); let clone = selected.cloneNode();
original.setAttributeNS(null, 'y', 0); clone.classList.remove(selectedClass);
clone.classList.add('clone');
original.parentElement.appendChild(counter); selected.dataset.previous = prevCoords;
point.parentElement.appendChild(original); selected.parentElement.appendChild(clone);
point.parentElement.appendChild(selected);
if (counter.parentElement.querySelector('[href="#counter-prone"]')) { console.log(this.getCounterAndClones(troopAllegiance, troopNumber));
if (clone.parentElement.querySelector('[href="#counter-prone"]')) {
this.toggleProne(); this.toggleProne();
} }
let previous = this.getCellPosition(counter.parentElement), let previous = this.getCellPosition(clone.parentElement),
current = this.getCellPosition(original.parentElement); current = this.getCellPosition(selected.parentElement);
if (!trace) { if (!trace) {
trace = document.createElementNS(svgns, 'polyline'); trace = document.createElementNS(svgns, 'polyline');
@ -287,7 +279,7 @@ export default class Counter {
} }
trace.setAttributeNS(null, 'points', points); trace.setAttributeNS(null, 'points', points);
counter.addEventListener('click', this.clickClone.bind(this)); // clone.addEventListener('click', this.clickClone.bind(this));
} else { } else {
selected.removeAttribute('data-x'); selected.removeAttribute('data-x');
point.parentElement.appendChild(selected); point.parentElement.appendChild(selected);

View File

@ -4,14 +4,6 @@ import Counter from './counter.js';
const svgns = "http://www.w3.org/2000/svg"; const svgns = "http://www.w3.org/2000/svg";
function isEven(n) {
return n % 2 === 0;
}
function radToDeg(radians) {
return radians * 180 / Math.PI;
}
export default class Game { export default class Game {
info; info;
placing = []; placing = [];
@ -27,7 +19,6 @@ export default class Game {
this.sightLine = new SightLine(svg); this.sightLine = new SightLine(svg);
this.counter = new Counter(svg, this); this.counter = new Counter(svg, this);
// this.setUpCounter(this);
this.setUpCells(); this.setUpCells();
} }
@ -59,8 +50,12 @@ export default class Game {
return this.svg.querySelectorAll('#firing-arcs polygon:not([clip-path])'); return this.svg.querySelectorAll('#firing-arcs polygon:not([clip-path])');
} }
getGridIndex({ parentElement }) { getGridIndex({ parentElement: { dataset: { x }, parentElement: { dataset: { y }}}}) {
return { x: parentElement.dataset.x, y: parentElement.parentElement.dataset.y }; return { x, y };
}
getCounterAtGridIndex(x, y) {
return this.getCell(x, y).querySelector('use[href*="#t-"');
} }
getBoard() { getBoard() {
@ -141,33 +136,109 @@ export default class Game {
let group = cell, let group = cell,
point = this.getHex(cell); point = this.getHex(cell);
point.addEventListener('click', e => { function isGrenade(el) {
const toPlace = this.placing.pop(); return el && el.getAttribute('href') === '#counter-grenade';
}
// TODO function isClone(counter) {
let existingOccupant = const isClone = counter.classList.contains('clone'),
this.svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`); { allegiance: clAl, number: clNum } = counter.dataset;
if (toPlace && toPlace.getAttribute('href') === '#counter-grenade') { return {
point.parentElement.appendChild(toPlace); of: function ({ dataset: { allegiance, number }}) {
return; return isClone && clAl == allegiance && clNum == number;
}
if (this.getSelected() && !existingOccupant) {
let sl = this.svg.querySelector('.sight-line');
this.placing.push(toPlace);
this.counter.place(point);
if (sl) {
if (sl.classList.contains('active')) {
this.sightLine.clear();
} else {
this.sightLine.update(point, this.getCellPosition(point.parentElement));
}
} }
};
}
cell.addEventListener('click', e => {
const state = {
placing: this.placing,
hex: cell.querySelector('use[href="#hex"]'),
occupant: cell.querySelector('use[href*="#t-"'),
contents: cell.querySelectorAll('*:not(use[href="#hex"])')
};
let toPlace = this.placing.pop();
if (isGrenade(toPlace)) {
state.hex.after(toPlace);
} else if (toPlace && !state.occupant) {
this.counter.place(point);
this.placing.push(toPlace);
} else if (toPlace && state.occupant) {
if (toPlace === state.occupant) {
if ('previous' in toPlace.dataset) {
toPlace.remove();
toPlace = this.getCounterAtGridIndex(...toPlace.dataset.previous.split(','));
toPlace.classList.remove('clone');
toPlace.classList.add('selected');
console.log(toPlace);
this.placing.push(toPlace);
} else {
this.counter.unSelect();
}
} else if (!state.occupant.classList.contains('clone')) {
this.counter.select(state.occupant);
this.placing.push(state.occupant);
} else {
if (isClone(state.occupant).of(toPlace)) {
if (!('previous' in state.occupant.dataset)) {
state.occupant.classList.remove('clone');
state.occupant.classList.add('selected');
toPlace.remove();
toPlace = state.occupant;
this.counter.removeClones(toPlace);
} else {
const index = this.getGridIndex(state.occupant);
let current = toPlace;
while (current.dataset.previous != `${index.x},${index.y}`) {
current = this.getCounterAtGridIndex(...current.dataset.previous.split(','));
}
current.dataset.previous = state.occupant.dataset.previous;
state.occupant.remove();
}
}
this.placing.push(toPlace);
}
} else if (!toPlace && state.occupant) {
this.counter.select(state.occupant);
this.placing.push(state.occupant);
} else {
console.log('removing cell contents');
state.contents.forEach(el => el.remove());
} }
}); });
// point.addEventListener('click', e => {
// const toPlace = this.placing.pop();
// // TODO
// let existingOccupant =
// this.svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`);
// if (toPlace && toPlace.getAttribute('href') === '#counter-grenade') {
// point.after(toPlace);
// return;
// }
// if (this.getSelected() && !existingOccupant) {
// let sl = this.svg.querySelector('.sight-line');
// this.placing.push(toPlace);
// this.counter.place(point);
// if (sl) {
// if (sl.classList.contains('active')) {
// this.sightLine.clear();
// } else {
// this.sightLine.update(point, this.getCellPosition(point.parentElement));
// }
// }
// }
// });
// Logic for this event: // Logic for this event:
// If there's a locked sightline, unlock it. Otherwise, if there's an // If there's a locked sightline, unlock it. Otherwise, if there's an
// active sightline, lock it. // active sightline, lock it.
@ -233,7 +304,6 @@ export default class Game {
setGrenade() { setGrenade() {
let counter = document.createElementNS(svgns, 'use'); let counter = document.createElementNS(svgns, 'use');
counter.setAttributeNS(null, 'href', '#counter-grenade'); counter.setAttributeNS(null, 'href', '#counter-grenade');
counter.addEventListener('click', () => counter.remove());
this.placing.push(counter); this.placing.push(counter);
} }