Extract scenario-build function into separate module
This commit is contained in:
parent
2d30b5f842
commit
6200e19de1
@ -186,13 +186,11 @@ polygon.firing-arc[data-allegiance="attacker"] {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
|
||||
.soldier-record svg.weapon-icon use {
|
||||
stroke: white;
|
||||
stroke-width: 0.5px;
|
||||
}
|
||||
|
||||
|
||||
.soldier-record svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
109
src/index.js
109
src/index.js
@ -3,6 +3,7 @@ import * as gameboard from './modules/gameboard.js';
|
||||
import * as recordSheet from './modules/record_sheet.js';
|
||||
import * as mapSelectDialog from './modules/map_select_dialog.js';
|
||||
import { Observable } from './modules/observable.js';
|
||||
import { requestResource, build } from './modules/scenario.js';
|
||||
import { scenarios } from './modules/scenarios.js';
|
||||
|
||||
globalThis.svgns = 'http://www.w3.org/2000/svg';
|
||||
@ -49,121 +50,21 @@ const mapPlaceholder = document.querySelector('.map-placeholder'),
|
||||
|
||||
let scenarioTemplate;
|
||||
|
||||
async function requestResource(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.responseType = 'document';
|
||||
|
||||
request.onload = function() {
|
||||
if (request.status === 200) {
|
||||
resolve(request.response);
|
||||
} else {
|
||||
reject(Error('Image didn\'t load successfully; error code:' + request.statusText));
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = function() {
|
||||
reject(Error('There was a network error.'));
|
||||
};
|
||||
|
||||
request.send();
|
||||
});
|
||||
}
|
||||
|
||||
async function loadScript(scenario, svg) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const scriptEl = document.createElementNS("http://www.w3.org/2000/svg", 'script');
|
||||
|
||||
scriptEl.onload = () => {
|
||||
console.log('map.js loaded');
|
||||
resolve(scriptEl);
|
||||
};
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
async function buildScenario(req) {
|
||||
const svg = scenarioTemplate.querySelector('svg').cloneNode(true);
|
||||
|
||||
document.querySelector('object').contentDocument.querySelector('svg').remove();
|
||||
document.querySelector('object').contentDocument.append(svg);
|
||||
|
||||
gameboard.stop();
|
||||
recordSheet.stop();
|
||||
|
||||
const scenario = await req;
|
||||
const startLocs = scenario.querySelector('.start-locations');
|
||||
const gb = svg.querySelector('.gameboard');
|
||||
const grid = svg.querySelector('.grid');
|
||||
const svg = scenarioTemplate.querySelector('svg').cloneNode(true);
|
||||
document.querySelector('object').contentDocument.querySelector('svg').replaceWith(svg);
|
||||
|
||||
const externalResourceEls = Array.from(scenario.querySelectorAll('use[href*=".svg"'));
|
||||
await build(svg, req);
|
||||
|
||||
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 => requestResource(`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(svg.ownerDocument.importNode(node, true))
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
scenario.querySelectorAll('use.mapsheet').forEach(el =>
|
||||
gb.querySelector('#background').after(svg.ownerDocument.importNode(el, true))
|
||||
);
|
||||
|
||||
if (startLocs) grid.before(svg.ownerDocument.importNode(startLocs, true));
|
||||
|
||||
const scenarioGrid = scenario.querySelector('.grid');
|
||||
|
||||
if (scenarioGrid) {
|
||||
grid.replaceWith(svg.ownerDocument.importNode(scenarioGrid, true));
|
||||
}
|
||||
|
||||
await loadScript(scenario, svg);
|
||||
mapResourceEl.style.opacity = 1;
|
||||
mapPlaceholder.style.opacity = 0;
|
||||
|
||||
panzoom.start(svg);
|
||||
gameboard.start(svg);
|
||||
recordSheet.start(startLocs, gameboard.getUnits());
|
||||
recordSheet.start(svg.querySelector('.start-locations'), gameboard.getUnits());
|
||||
}
|
||||
|
||||
function updateTurnCounter() {
|
||||
|
102
src/modules/scenario.js
Normal file
102
src/modules/scenario.js
Normal file
@ -0,0 +1,102 @@
|
||||
async function loadScript(scenario, svg) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const scriptEl = document.createElementNS("http://www.w3.org/2000/svg", 'script');
|
||||
|
||||
scriptEl.onload = () => {
|
||||
console.log('map.js loaded');
|
||||
resolve();
|
||||
};
|
||||
|
||||
scriptEl.onerror = () => {
|
||||
reject(Error('Script failed to load.'));
|
||||
};
|
||||
|
||||
const dataset = scenario.querySelector('script').dataset;
|
||||
|
||||
if ('cols' in dataset && 'rows' in dataset) {
|
||||
scriptEl.dataset.rows = dataset.rows;
|
||||
scriptEl.dataset.cols = dataset.cols;
|
||||
}
|
||||
|
||||
scriptEl.setAttributeNS(null, 'href', '../../map.js');
|
||||
svg.append(scriptEl);
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestResource(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.responseType = 'document';
|
||||
|
||||
request.onload = function() {
|
||||
if (request.status === 200) {
|
||||
resolve(request.response);
|
||||
} else {
|
||||
reject(Error('Image didn\'t load successfully; error code:' + request.statusText));
|
||||
}
|
||||
};
|
||||
|
||||
request.onerror = function() {
|
||||
reject(Error('There was a network error.'));
|
||||
};
|
||||
|
||||
request.send();
|
||||
});
|
||||
}
|
||||
|
||||
export async function build(svg, request) {
|
||||
const gb = svg.querySelector('.gameboard');
|
||||
const grid = svg.querySelector('.grid');
|
||||
|
||||
const scenario = await request;
|
||||
const startLocs = scenario.querySelector('.start-locations');
|
||||
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 => requestResource(`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(svg.ownerDocument.importNode(node, true))
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
scenario.querySelectorAll('use.mapsheet').forEach(el =>
|
||||
gb.querySelector('#background').after(svg.ownerDocument.importNode(el, true))
|
||||
);
|
||||
|
||||
if (startLocs) grid.before(svg.ownerDocument.importNode(startLocs, true));
|
||||
|
||||
const scenarioGrid = scenario.querySelector('.grid');
|
||||
|
||||
if (scenarioGrid) {
|
||||
grid.replaceWith(svg.ownerDocument.importNode(scenarioGrid, true));
|
||||
}
|
||||
|
||||
return loadScript(scenario, svg);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user