135 lines
3.6 KiB
JavaScript
135 lines
3.6 KiB
JavaScript
const svgns = "http://www.w3.org/2000/svg",
|
|
selectedClass = 'selected';
|
|
|
|
function dataSelector({ dataset: { allegiance, number }}) {
|
|
return `[data-number="${number}"][data-allegiance="${allegiance}"]`;
|
|
}
|
|
|
|
function traceSelector(counter) {
|
|
return `polyline.move-trace${dataSelector(counter)}`;
|
|
}
|
|
|
|
function 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;
|
|
}
|
|
|
|
function getClones(svg, counter) {
|
|
return svg.querySelectorAll(`.counter.clone${dataSelector(counter)}`);
|
|
}
|
|
|
|
function getCounterAndClones(svg, counter) {
|
|
return svg.querySelectorAll(`.counter${dataSelector(counter)}`);
|
|
}
|
|
|
|
export function getCounter(svg, selected) {
|
|
return svg.querySelector(`.counter${dataSelector(selected)}:not(.clone)`);
|
|
}
|
|
|
|
export function getTrace(svg, counter) {
|
|
return svg.querySelector(traceSelector(counter));
|
|
}
|
|
|
|
export function place(svg, selected, cell) {
|
|
let points,
|
|
counterNodeList = getCounterAndClones(svg, selected);
|
|
|
|
if (counterNodeList.length > 0 && selected.parentElement.hasAttribute('data-x')) {
|
|
let trace = svg.querySelector(traceSelector(selected));
|
|
|
|
let prevCoords = [
|
|
selected.parentElement.dataset.x,
|
|
selected.parentElement.parentElement.dataset.y
|
|
]
|
|
|
|
let clone = selected.cloneNode(true);
|
|
clone.classList.remove(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 = getCellPosition(clone.parentElement),
|
|
current = 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');
|
|
|
|
svg.querySelector('.board').prepend(trace);
|
|
} else {
|
|
points = `${trace.getAttribute('points')} ${current.x},${current.y}`;
|
|
}
|
|
|
|
trace.setAttributeNS(null, 'points', points);
|
|
} else {
|
|
selected.removeAttribute('data-x');
|
|
cell.appendChild(selected);
|
|
}
|
|
}
|
|
|
|
export function removeClones(svg, counter) {
|
|
getClones(svg, counter).forEach(c => c.remove());
|
|
}
|
|
|
|
export function endMove(svg, counter) {
|
|
const trace = svg.querySelector(traceSelector(counter)),
|
|
proneCounter = counter.querySelector('[href="#counter-prone"]');
|
|
|
|
if (trace) {
|
|
trace.remove();
|
|
}
|
|
|
|
delete counter.dataset.previous;
|
|
|
|
if (proneCounter) {
|
|
proneCounter.dataset.preexisting = '';
|
|
}
|
|
|
|
removeClones(counter);
|
|
}
|
|
|
|
export function hasProne(counter) {
|
|
return !!counter.querySelector('[href="#counter-prone"]');
|
|
}
|
|
|
|
export function 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();
|
|
}
|
|
}
|
|
|
|
export function getSelectedClass() {
|
|
return selectedClass;
|
|
}
|