WIP: use scenario template to build scenarios client-side
This commit is contained in:
246
src/index.js
246
src/index.js
@@ -40,16 +40,134 @@ const mapPlaceholder = document.querySelector('.map-placeholder'),
|
||||
|
||||
let mapResourceEl = document.querySelector('object');
|
||||
|
||||
async function requestScenario(url) {
|
||||
return new Promise((res, rej) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.responseType = 'document';
|
||||
|
||||
request.onload = function() {
|
||||
if (request.status === 200) {
|
||||
res(request.response);
|
||||
} else {
|
||||
rej(Error('Image didn\'t load successfully; error code:' + request.statusText));
|
||||
}
|
||||
};
|
||||
request.onerror = function() {
|
||||
rej(Error('There was a network error.'));
|
||||
};
|
||||
|
||||
request.send();
|
||||
});
|
||||
}
|
||||
|
||||
const scenarioRequest = requestScenario(map);
|
||||
|
||||
function loadScenario(data) {
|
||||
const current = document.querySelector('object');
|
||||
const next = document.createElement('object');
|
||||
next.setAttribute('type', 'image/svg+xml');
|
||||
next.style.opacity = 0;
|
||||
next.addEventListener('load', load);
|
||||
mapPlaceholder.style.opacity = 1;
|
||||
next.data = data;
|
||||
mapPlaceholder.after(next);
|
||||
current.remove();
|
||||
// const current = document.querySelector('object');
|
||||
// const next = document.createElement('object');
|
||||
// next.setAttribute('type', 'image/svg+xml');
|
||||
// next.style.opacity = 0;
|
||||
// next.addEventListener('load', load);
|
||||
// mapPlaceholder.style.opacity = 1;
|
||||
// next.data = data;
|
||||
// mapPlaceholder.after(next);
|
||||
// current.remove();
|
||||
|
||||
buildScenario(requestScenario(data));
|
||||
}
|
||||
|
||||
async function buildScenario(req) {
|
||||
console.log('req', req);
|
||||
|
||||
const svg = scenarioTemplate.querySelector('svg').cloneNode(true);
|
||||
document.querySelector('object').contentDocument.querySelector('svg').replaceWith(svg);
|
||||
|
||||
const startLocs = svg.querySelector('.start-locations');
|
||||
const scenario = await req;
|
||||
|
||||
console.log(scenario);
|
||||
|
||||
const gb = svg.querySelector('.gameboard');
|
||||
const grid = svg.querySelector('.grid');
|
||||
|
||||
const externalResourceEls = Array.from(scenario.querySelectorAll('use[href*=".svg"'));
|
||||
|
||||
const refs = externalResourceEls.reduce((acc, el) => {
|
||||
const href = el.getAttributeNS(null, 'href');
|
||||
const [filename] = href.match(/.+\.svg/);
|
||||
const fragmentIdentifier = href.split('.svg').pop();
|
||||
|
||||
(acc[filename] ??= new Set()).add(fragmentIdentifier);
|
||||
el.setAttributeNS(null, 'href', fragmentIdentifier);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
await Promise.all(
|
||||
Object.keys(refs).map(filename => requestScenario(`assets/images/${filename}`))
|
||||
).then(result => {
|
||||
const defs = svg.querySelector('defs');
|
||||
|
||||
Object.keys(refs).forEach((filename, index) => {
|
||||
const external = result[index];
|
||||
|
||||
refs[filename].forEach(fragmentIdentifier => {
|
||||
external
|
||||
.querySelectorAll(`${fragmentIdentifier} use`)
|
||||
.forEach(el => refs[filename].add(el.getAttributeNS(null, 'href')));
|
||||
});
|
||||
|
||||
const refsQuery = [...refs[filename]].join(', ');
|
||||
external.querySelectorAll(refsQuery).forEach(node => defs.append(node));
|
||||
});
|
||||
});
|
||||
|
||||
scenario.querySelectorAll('use.mapsheet').forEach(el => gb.prepend(el));
|
||||
grid.before(scenario.querySelector('.start-locations'));
|
||||
|
||||
const scenarioGrid = scenario.querySelector('.grid');
|
||||
|
||||
console.log('scenarioGrid', scenarioGrid);
|
||||
|
||||
if (scenarioGrid) {
|
||||
grid.replaceWith(svg.ownerDocument.importNode(scenarioGrid, true));
|
||||
}
|
||||
|
||||
async function loadScript() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const scriptEl = document.createElementNS("http://www.w3.org/2000/svg", 'script');
|
||||
// const scriptEl = svg.ownerDocument.importNode(scenario.querySelector('script'));
|
||||
|
||||
scriptEl.onload = () => {
|
||||
console.log('map.js loaded');
|
||||
resolve();
|
||||
};
|
||||
|
||||
scriptEl.onerror = () => {
|
||||
reject(Error('Script failed to load.'));
|
||||
};
|
||||
|
||||
const oldScript = scenario.querySelector('script');
|
||||
|
||||
if ('cols' in oldScript.dataset && 'rows' in oldScript.dataset) {
|
||||
scriptEl.dataset.rows = oldScript.dataset.rows;
|
||||
scriptEl.dataset.cols = oldScript.dataset.cols;
|
||||
}
|
||||
|
||||
scriptEl.setAttributeNS(null, 'href', '../../map.js');
|
||||
svg.append(scriptEl);
|
||||
});
|
||||
}
|
||||
|
||||
await loadScript();
|
||||
|
||||
// this.style.opacity = 1;
|
||||
// mapPlaceholder.style.opacity = 0;
|
||||
|
||||
panzoom.start(svg);
|
||||
gameboard.start(svg);
|
||||
recordSheet.start(startLocs, gameboard.getUnits());
|
||||
}
|
||||
|
||||
function updateTurnCounter() {
|
||||
@@ -91,23 +209,82 @@ function roll(die) {
|
||||
return numsAsWords[getRandomIntInclusive(0, numsAsWords.length - 1)];
|
||||
}
|
||||
|
||||
function load() {
|
||||
let scenarioTemplate;
|
||||
|
||||
async function load() {
|
||||
const svg = this.contentDocument.querySelector('svg'),
|
||||
startLocs = svg.querySelector('.start-locations')
|
||||
// , scriptEl = this.contentDocument.querySelector('script')
|
||||
;
|
||||
|
||||
scenarioTemplate = this.contentDocument.cloneNode(svg);
|
||||
buildScenario(scenarioRequest);
|
||||
// const scenario = await scenarioRequest;
|
||||
// const gb = svg.querySelector('.gameboard');
|
||||
// const grid = svg.querySelector('.grid');
|
||||
|
||||
// const useEls = svg.querySelectorAll('use[href*=".svg"]');
|
||||
// const externalResourceEls = Array.from(scenario.querySelectorAll('use[href*=".svg"'));
|
||||
|
||||
// console.log(useEls);
|
||||
// const refs = externalResourceEls.reduce((acc, el) => {
|
||||
// const href = el.getAttributeNS(null, 'href');
|
||||
// const [filename] = href.match(/.+\.svg/);
|
||||
// const fragmentIdentifier = href.split('.svg').pop();
|
||||
|
||||
// [...new Set([...useEls].map(el => el.getAttributeNS(null, 'href').match(/^(.*?)\.svg/g).at(0)))].forEach(f => {
|
||||
// const name = `../assets/images/${f}`;
|
||||
// import(name);
|
||||
// console.log(f);
|
||||
// (acc[filename] ??= new Set()).add(fragmentIdentifier);
|
||||
// el.setAttributeNS(null, 'href', fragmentIdentifier);
|
||||
|
||||
// return acc;
|
||||
// }, {});
|
||||
|
||||
// await Promise.all(
|
||||
// Object.keys(refs).map(filename => requestScenario(`assets/images/${filename}`))
|
||||
// ).then(result => {
|
||||
// const defs = svg.querySelector('defs');
|
||||
|
||||
// Object.keys(refs).forEach((filename, index) => {
|
||||
// const external = result[index];
|
||||
|
||||
// refs[filename].forEach(fragmentIdentifier => {
|
||||
// external
|
||||
// .querySelectorAll(`${fragmentIdentifier} use`)
|
||||
// .forEach(el => refs[filename].add(el.getAttributeNS(null, 'href')));
|
||||
// });
|
||||
|
||||
// const refsQuery = [...refs[filename]].join(', ');
|
||||
// external.querySelectorAll(refsQuery).forEach(node => defs.append(node));
|
||||
// });
|
||||
// });
|
||||
|
||||
// scenario.querySelectorAll('use.mapsheet').forEach(el => gb.prepend(el));
|
||||
// grid.before(scenario.querySelector('.start-locations'));
|
||||
|
||||
// async function loadScript() {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const scriptEl = document.createElementNS("http://www.w3.org/2000/svg", 'script');
|
||||
// // const scriptEl = svg.ownerDocument.importNode(scenario.querySelector('script'));
|
||||
|
||||
// scriptEl.onload = () => {
|
||||
// console.log('map.js loaded');
|
||||
// resolve();
|
||||
// };
|
||||
|
||||
// scriptEl.onerror = () => {
|
||||
// reject(Error('Script failed to load.'));
|
||||
// };
|
||||
|
||||
// scriptEl.dataset.rows = scenario.querySelector('script').dataset.rows;
|
||||
// scriptEl.dataset.cols = scenario.querySelector('script').dataset.cols;
|
||||
// scriptEl.setAttributeNS(null, 'href', '../../map.js');
|
||||
// svg.append(scriptEl);
|
||||
// });
|
||||
// }
|
||||
|
||||
// await loadScript();
|
||||
|
||||
this.style.opacity = 1;
|
||||
mapPlaceholder.style.opacity = 0;
|
||||
// URL.revokeObjectURL(this.data);
|
||||
|
||||
// const linkEl = document.createElement('link');
|
||||
// linkEl.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
|
||||
// linkEl.setAttribute('rel', 'stylesheet');
|
||||
@@ -116,25 +293,13 @@ function load() {
|
||||
|
||||
// linkEl.onload = function (e) {
|
||||
// console.log('map.css loaded');
|
||||
|
||||
// if (scriptEl) {
|
||||
// scriptEl.onload = function () {
|
||||
// console.log('map.js loaded');
|
||||
|
||||
// };
|
||||
// scriptEl.setAttribute('href', '../../map.js');
|
||||
// }
|
||||
// };
|
||||
|
||||
// svg.prepend(linkEl);
|
||||
|
||||
this.style.opacity = 1;
|
||||
mapPlaceholder.style.opacity = 0;
|
||||
URL.revokeObjectURL(this.data);
|
||||
|
||||
panzoom.start(svg);
|
||||
gameboard.start(svg);
|
||||
recordSheet.start(startLocs, gameboard.getUnits());
|
||||
// panzoom.start(svg);
|
||||
// gameboard.start(svg);
|
||||
// recordSheet.start(startLocs, gameboard.getUnits());
|
||||
}
|
||||
|
||||
document.querySelectorAll('.end-turn').forEach(el =>
|
||||
@@ -199,7 +364,19 @@ document.querySelector('#upload-save').addEventListener('click', () => {
|
||||
|
||||
document.querySelector('input[type="file"]').addEventListener('change', e => {
|
||||
const [file] = fileInputEl.files;
|
||||
loadScenario(URL.createObjectURL(file))
|
||||
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(reader.result, "image/svg+xml");
|
||||
|
||||
buildScenario(doc);
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
|
||||
// loadScenario(URL.createObjectURL(file));
|
||||
});
|
||||
|
||||
document.querySelector('#roll-dice').addEventListener('click', () => {
|
||||
@@ -221,8 +398,9 @@ mapSelectDialog
|
||||
.changeMapOnConfirm(loadScenario);
|
||||
|
||||
mapResourceEl.addEventListener('load', load);
|
||||
mapResourceEl.data = map;
|
||||
mapResourceEl = null;
|
||||
// mapResourceEl.data = map;
|
||||
// mapResourceEl = null;
|
||||
|
||||
|
||||
dice.forEach(el => {
|
||||
el.classList.add(roll(d6));
|
||||
|
||||
Reference in New Issue
Block a user