217 lines
6.6 KiB
JavaScript
217 lines
6.6 KiB
JavaScript
import { pan, zoom } from 'svg-pan-zoom';
|
|
import Game from './modules/game.js';
|
|
|
|
const PanZoom = new function () {
|
|
const vb = 'viewBox';
|
|
|
|
function storeLatestViewBoxVal(svg) {
|
|
const observer = new MutationObserver(mutations => {
|
|
if (mutations.find(m => m.target == svg && m.attributeName == vb)) {
|
|
localStorage.setItem(vb, svg.getAttribute(vb));
|
|
}
|
|
});
|
|
|
|
observer.observe(svg, { attributes: true });
|
|
}
|
|
|
|
function restoreViewboxVal(svg) {
|
|
const storedVbVal = localStorage.getItem(vb);
|
|
|
|
if (storedVbVal) {
|
|
svg.setAttributeNS(null, vb, storedVbVal);
|
|
}
|
|
}
|
|
|
|
this.start = function (svg) {
|
|
restoreViewboxVal(svg);
|
|
|
|
svg.addEventListener('wheel', e => {
|
|
e.preventDefault();
|
|
|
|
svg.setAttributeNS(null, vb, zoom(svg, e));
|
|
}, { passive: false });
|
|
|
|
svg.addEventListener('pointerdown', e => {
|
|
e.preventDefault();
|
|
|
|
pan(svg, e);
|
|
}, { passive: false });
|
|
|
|
storeLatestViewBoxVal(svg);
|
|
};
|
|
};
|
|
|
|
const RecordSheet = new function () {
|
|
this.unSelect = function () {
|
|
let selected = this.getSelected();
|
|
|
|
if (selected) {
|
|
selected.classList.remove('selected');
|
|
document.getElementById('toggle-prone-counter').checked = false;
|
|
}
|
|
};
|
|
|
|
this.getSelected = function () {
|
|
return document.querySelector('.soldier-record.selected');
|
|
};
|
|
|
|
this.select = function (el) {
|
|
let { troopNumber, troopAllegiance } = el.dataset;
|
|
// proneStatus = svg.Counter.hasProne(troopNumber, troopAllegiance);
|
|
|
|
this.unSelect();
|
|
document.querySelector(`#record-sheet .soldier-record[data-troop-number="${troopNumber}"][data-troop-allegiance="${troopAllegiance}"]`).classList.add('selected');
|
|
// document.getElementById('toggle-prone-counter').checked = proneStatus;
|
|
};
|
|
|
|
this.endMove = function() {
|
|
const selected = this.getSelected();
|
|
|
|
if (selected) {
|
|
selected.classList.toggle('movement-ended');
|
|
}
|
|
|
|
this.unSelect();
|
|
};
|
|
};
|
|
|
|
window.addEventListener('load', () => {
|
|
const svg = document.querySelector('object').contentDocument.querySelector('svg'),
|
|
game = new Game(svg);
|
|
|
|
const svgns = "http://www.w3.org/2000/svg",
|
|
recordSheetVisibility = document.querySelector('#content input[type="checkbox"].visible');
|
|
|
|
PanZoom.start(svg);
|
|
|
|
game.info = document.getElementById('status');
|
|
|
|
// Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => {
|
|
// const identityMtx = [1, 0, 0, 1, 0, 0];
|
|
// const target = document.getElementById(fieldset.name);
|
|
// const transform = getComputedStyle(target).transform.match(/-?\d+\.?\d*/g) || identityMtx;
|
|
// const inputs = fieldset.querySelectorAll('input');
|
|
|
|
// if (transform) {
|
|
// const [a, b, c, d, e, f] = transform.map(n => parseFloat(n));
|
|
|
|
// // a c e
|
|
// // b d f
|
|
|
|
// const scaleX = Math.sqrt(a**2 + c**2);
|
|
// const scaleY = Math.sqrt(b**2 + d**2);
|
|
|
|
// let values = {
|
|
// scaleX: Math.round(scaleX * 1000) / 1000,
|
|
// scaleY: Math.round(scaleY * 1000) / 1000,
|
|
// translateX: e,
|
|
// translateY: f,
|
|
// rotate: Math.round(radToDeg((Math.acos(a / scaleX) + Math.asin(b / scaleY)) / 2) * 10) / 10
|
|
// }
|
|
|
|
// inputs.forEach(input => input.value = values[input.name]);
|
|
// }
|
|
|
|
// inputs.forEach(input => {
|
|
// input.addEventListener('pointerenter', e => e.target.focus());
|
|
|
|
// input.addEventListener('input', e => {
|
|
// let { translateX, translateY, rotate, scaleX, scaleY } =
|
|
// Object.values(inputs).reduce((acc, input) => {
|
|
// acc[input.name] = input.value;
|
|
// return acc;
|
|
// }, {});
|
|
|
|
// let transform = `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg) scale(${scaleX}, ${scaleY})`;
|
|
// target.style.transform = transform;
|
|
// });
|
|
|
|
// input.addEventListener('pointerleave', () => document.activeElement.blur());
|
|
// });
|
|
// });
|
|
|
|
document.querySelectorAll('.soldier-record').forEach(el =>
|
|
el.addEventListener('click', e => {
|
|
if (el.classList.contains('selected')) {
|
|
el.classList.remove('selected');
|
|
RecordSheet.unSelect();
|
|
// Counter.unSelect();
|
|
} else {
|
|
RecordSheet.select(el);
|
|
// Counter.select(el);
|
|
}
|
|
|
|
// SightLine.clear();
|
|
})
|
|
);
|
|
|
|
document.querySelectorAll('.end-move').forEach(el => el.addEventListener('click', e => game.endMove()));
|
|
|
|
document.querySelectorAll('.end-turn').forEach(el =>
|
|
el.addEventListener('click', ({ target: { dataset: { allegiance }}}) => {
|
|
let dataSelector = `[data-troop-allegiance="${allegiance}"]`,
|
|
records = Array.from(document.querySelectorAll(`.soldier-record${dataSelector}`)),
|
|
turnCounter = document.getElementById('turn-count'),
|
|
{ textContent: count, dataset: { update }} = turnCounter;
|
|
|
|
el.setAttribute('disabled', '');
|
|
|
|
document
|
|
.querySelector(`button.end-turn:not([data-allegiance="${allegiance}"])`)
|
|
.removeAttribute('disabled');
|
|
|
|
if (update == '1') {
|
|
turnCounter.children.namedItem('count').textContent++
|
|
turnCounter.dataset.update = '0';
|
|
} else {
|
|
turnCounter.dataset.update = '1';
|
|
}
|
|
|
|
// qA(`#firing-arcs ${dataSelector}`).forEach(el => el.remove());
|
|
|
|
records
|
|
.sort((el1, el2) => el1.dataset.troopNumber > el2.dataset.troopNumber)
|
|
.forEach(el => el.classList.remove('movement-ended'));
|
|
|
|
// RecordSheet.select(records.at(0));
|
|
// Counter.select(records.at(0));
|
|
})
|
|
);
|
|
|
|
document.querySelectorAll('.set-firing-arc').forEach(el =>
|
|
el.addEventListener('click', () => game.setFiringArc(el.dataset.size))
|
|
);
|
|
|
|
recordSheetVisibility.addEventListener('input', e => {
|
|
let divs = document.querySelectorAll('#content div');
|
|
|
|
divs.forEach(d => {
|
|
if (recordSheetVisibility.checked) {
|
|
d.style.display = d.id == 'record-sheet' ? 'flex' : 'block';
|
|
} else {
|
|
d.style.display = 'none';
|
|
}
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('#toggle-firing-arc-vis input').forEach(el => el.addEventListener('input', e => {
|
|
game.toggleFiringArcVisibility(el.dataset.allegiance);
|
|
}));
|
|
|
|
document.getElementById('toggle-prone-counter').addEventListener('input', function (e) {
|
|
let selected = RecordSheet.getSelected();
|
|
|
|
if (selected) {
|
|
let template = q(`g#${selected.dataset.troopAllegiance}-${selected.dataset.troopNumber}`);
|
|
|
|
if (this.checked) {
|
|
let counter = document.createElementNS(svgns, 'use');
|
|
counter.setAttributeNS(null, 'href', '#counter-prone');
|
|
template.appendChild(counter);
|
|
} else {
|
|
template.querySelector('[href="#counter-prone"]').remove();
|
|
}
|
|
}
|
|
});
|
|
});
|