Web Dev Solutions

Catalin Mititiuc

const 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; }