merge editor uis

This commit is contained in:
Peter 2022-11-27 16:35:40 -05:00
parent cf017b4943
commit 8875f5d10a
8 changed files with 368 additions and 419 deletions

View file

@ -1,13 +1,13 @@
'use strict';
"use strict";
function editBurg(id) {
if (customization) return;
closeDialogs('.stable');
if (!layerIsOn('toggleIcons')) toggleIcons();
if (!layerIsOn('toggleLabels')) toggleLabels();
closeDialogs(".stable");
if (!layerIsOn("toggleIcons")) toggleIcons();
if (!layerIsOn("toggleLabels")) toggleLabels();
const burg = id || d3.event.target.dataset.id;
elSelected = burgLabels.select("[data-id='" + burg + "']");
burgLabels.selectAll('text').call(d3.drag().on('start', dragBurgLabel)).classed('draggable', true);
burgLabels.selectAll("text").call(d3.drag().on("start", dragBurgLabel)).classed("draggable", true);
updateBurgValues();
$("#burgEditor").dialog({
@ -21,12 +21,12 @@ function editBurg(id) {
modules.editBurg = true;
// add listeners
document.getElementById('burgGroupShow').addEventListener('click', showGroupSection);
document.getElementById('burgGroupHide').addEventListener('click', hideGroupSection);
document.getElementById('burgSelectGroup').addEventListener('change', changeGroup);
document.getElementById('burgInputGroup').addEventListener('change', createNewGroup);
document.getElementById('burgAddGroup').addEventListener('click', toggleNewGroupInput);
document.getElementById('burgRemoveGroup').addEventListener('click', removeBurgsGroup);
document.getElementById("burgGroupShow").addEventListener("click", showGroupSection);
document.getElementById("burgGroupHide").addEventListener("click", hideGroupSection);
document.getElementById("burgSelectGroup").addEventListener("change", changeGroup);
document.getElementById("burgInputGroup").addEventListener("change", createNewGroup);
document.getElementById("burgAddGroup").addEventListener("click", toggleNewGroupInput);
document.getElementById("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
document.getElementById("burgName").addEventListener("input", changeName);
document.getElementById("burgNameReRandom").addEventListener("click", generateNameRandom);
@ -39,11 +39,11 @@ function editBurg(id) {
document.getElementById("regenerateMFCGBurgSeed").addEventListener("click", randomizeSeed);
document.getElementById("addCustomMFCGBurgLink").addEventListener("click", addCustomMfcgLink);
document.getElementById('burgStyleShow').addEventListener('click', showStyleSection);
document.getElementById('burgStyleHide').addEventListener('click', hideStyleSection);
document.getElementById('burgEditLabelStyle').addEventListener('click', editGroupLabelStyle);
document.getElementById('burgEditIconStyle').addEventListener('click', editGroupIconStyle);
document.getElementById('burgEditAnchorStyle').addEventListener('click', editGroupAnchorStyle);
document.getElementById("burgStyleShow").addEventListener("click", showStyleSection);
document.getElementById("burgStyleHide").addEventListener("click", hideStyleSection);
document.getElementById("burgEditLabelStyle").addEventListener("click", editGroupLabelStyle);
document.getElementById("burgEditIconStyle").addEventListener("click", editGroupIconStyle);
document.getElementById("burgEditAnchorStyle").addEventListener("click", editGroupAnchorStyle);
document.getElementById("burgEmblem").addEventListener("click", openEmblemEdit);
document.getElementById("burgToggleMFCGMap").addEventListener("click", toggleMFCGMap);
@ -55,8 +55,12 @@ function editBurg(id) {
document.getElementById("burgTemperatureGraph").addEventListener("click", showTemperatureGraph);
function updateBurgValues() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
const b = pack.burgs[id];
const province = pack.cells.province[b.cell];
const provinceName = province ? pack.provinces[province].fullName + ", " : "";
const stateName = pack.states[b.state].fullName || pack.states[b.state].name;
document.getElementById("burgProvinceAndState").innerHTML = provinceName + stateName;
document.getElementById("burgName").value = b.name;
document.getElementById("burgType").value = b.type || "Generic";
@ -64,44 +68,43 @@ function editBurg(id) {
document.getElementById("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none";
// update list and select culture
const cultureSelect = document.getElementById('burgCulture');
const cultureSelect = document.getElementById("burgCulture");
cultureSelect.options.length = 0;
const cultures = pack.cultures.filter((c) => !c.removed);
cultures.forEach((c) => cultureSelect.options.add(new Option(c.name, c.i, false, c.i === b.culture)));
const cultures = pack.cultures.filter(c => !c.removed);
cultures.forEach(c => cultureSelect.options.add(new Option(c.name, c.i, false, c.i === b.culture)));
const temperature = grid.cells.temp[pack.cells.g[b.cell]];
document.getElementById('burgTemperature').innerHTML = convertTemperature(temperature);
document.getElementById('burgTemperatureLike').innerHTML = getTemperatureLikeness(temperature);
document.getElementById('burgElevation').innerHTML = getHeight(pack.cells.h[b.cell]);
document.getElementById("burgTemperature").innerHTML = convertTemperature(temperature);
document.getElementById("burgTemperatureLikeIn").innerHTML = getTemperatureLikeness(temperature);
document.getElementById("burgElevation").innerHTML = getHeight(pack.cells.h[b.cell]);
// toggle features
if (b.capital) document.getElementById('burgCapital').classList.remove('inactive');
else document.getElementById('burgCapital').classList.add('inactive');
if (b.port) document.getElementById('burgPort').classList.remove('inactive');
else document.getElementById('burgPort').classList.add('inactive');
if (b.citadel) document.getElementById('burgCitadel').classList.remove('inactive');
else document.getElementById('burgCitadel').classList.add('inactive');
if (b.walls) document.getElementById('burgWalls').classList.remove('inactive');
else document.getElementById('burgWalls').classList.add('inactive');
if (b.plaza) document.getElementById('burgPlaza').classList.remove('inactive');
else document.getElementById('burgPlaza').classList.add('inactive');
if (b.temple) document.getElementById('burgTemple').classList.remove('inactive');
else document.getElementById('burgTemple').classList.add('inactive');
if (b.shanty) document.getElementById('burgShanty').classList.remove('inactive');
else document.getElementById('burgShanty').classList.add('inactive');
if (b.capital) document.getElementById("burgCapital").classList.remove("inactive");
else document.getElementById("burgCapital").classList.add("inactive");
if (b.port) document.getElementById("burgPort").classList.remove("inactive");
else document.getElementById("burgPort").classList.add("inactive");
if (b.citadel) document.getElementById("burgCitadel").classList.remove("inactive");
else document.getElementById("burgCitadel").classList.add("inactive");
if (b.walls) document.getElementById("burgWalls").classList.remove("inactive");
else document.getElementById("burgWalls").classList.add("inactive");
if (b.plaza) document.getElementById("burgPlaza").classList.remove("inactive");
else document.getElementById("burgPlaza").classList.add("inactive");
if (b.temple) document.getElementById("burgTemple").classList.remove("inactive");
else document.getElementById("burgTemple").classList.add("inactive");
if (b.shanty) document.getElementById("burgShanty").classList.remove("inactive");
else document.getElementById("burgShanty").classList.add("inactive");
// economics block
document.getElementById('burgProduction').innerHTML = getProduction(b.produced);
document.getElementById("burgProduction").innerHTML = getProduction(b.produced);
const deals = pack.trade.deals;
document.getElementById('burgExport').innerHTML = getExport(deals.filter((deal) => deal.exporter === b.i));
document.getElementById('burgImport').innerHTML = '';
document.getElementById("burgExport").innerHTML = getExport(deals.filter((deal) => deal.exporter === b.i));
document.getElementById("burgImport").innerHTML = '';
//toggle lock
updateBurgLockIcon();
// select group
const group = elSelected.node().parentNode.id;
const select = document.getElementById('burgSelectGroup');
const select = document.getElementById("burgSelectGroup");
select.options.length = 0; // remove all options
burgLabels.selectAll("g").each(function () {
@ -162,47 +165,9 @@ function editBurg(id) {
return `${totalIncome}: ${exported.join('')}`;
}
function getProduction(pool) {
let html = '';
for (const resourceId in pool) {
const {name, unit, icon} = Resources.get(+resourceId);
const production = pool[resourceId];
const unitName = production > 1 ? unit + 's' : unit;
html += `<span data-tip="${name}: ${production} ${unitName}">
<svg class="resIcon"><use href="#${icon}"></svg>
<span style="margin: 0 0.2em 0 -0.2em">${production}</span>
</span>`;
}
return html;
}
function getExport(dealsArray) {
if (!dealsArray.length) return 'no';
const totalIncome = rn(d3.sum(dealsArray.map((deal) => deal.burgIncome)));
const exported = dealsArray.map((deal) => {
const {resourceId, quantity, burgIncome} = deal;
const {name, unit, icon} = Resources.get(resourceId);
const unitName = quantity > 1 ? unit + 's' : unit;
return `<span data-tip="${name}: ${quantity} ${unitName}. Income: ${rn(burgIncome)}">
<svg class="resIcon"><use href="#${icon}"></svg>
<span style="margin: 0 0.2em 0 -0.2em">${quantity}</span>
</span>`;
});
return `${totalIncome}: ${exported.join('')}`;
}
// in °C, array from -1 °C; source: https://en.wikipedia.org/wiki/List_of_cities_by_average_temperature
function getTemperatureLikeness(temperature) {
if (temperature < -15) return 'nowhere in the real-world';
if (temperature < -5) return 'in Yakutsk';
if (temperature > 31) return 'nowhere in the real-world';
if (temperature < -5) return "Yakutsk";
const cities = [
"Snag (Yukon)",
"Yellowknife (Canada)",
@ -272,18 +237,18 @@ function editBurg(id) {
}
function changeGroup() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
moveBurgToGroup(id, this.value);
}
function toggleNewGroupInput() {
if (burgInputGroup.style.display === 'none') {
burgInputGroup.style.display = 'inline-block';
if (burgInputGroup.style.display === "none") {
burgInputGroup.style.display = "inline-block";
burgInputGroup.focus();
burgSelectGroup.style.display = 'none';
burgSelectGroup.style.display = "none";
} else {
burgInputGroup.style.display = 'none';
burgSelectGroup.style.display = 'inline-block';
burgInputGroup.style.display = "none";
burgSelectGroup.style.display = "inline-block";
}
}
@ -298,16 +263,16 @@ function editBurg(id) {
.replace(/[^\w\s]/gi, "");
if (document.getElementById(group)) {
tip('Element with this id already exists. Please provide a unique name', false, 'error');
tip("Element with this id already exists. Please provide a unique name", false, "error");
return;
}
if (Number.isFinite(+group.charAt(0))) {
tip('Group name should start with a letter', false, 'error');
tip("Group name should start with a letter", false, "error");
return;
}
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
const oldGroup = elSelected.node().parentNode.id;
const label = document.querySelector("#burgLabels [data-id='" + id + "']");
@ -324,11 +289,11 @@ function editBurg(id) {
// just rename if only 1 element left
const count = elSelected.node().parentNode.childElementCount;
if (oldGroup !== 'cities' && oldGroup !== 'towns' && count === 1) {
document.getElementById('burgSelectGroup').selectedOptions[0].remove();
document.getElementById('burgSelectGroup').options.add(new Option(group, group, false, true));
if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) {
document.getElementById("burgSelectGroup").selectedOptions[0].remove();
document.getElementById("burgSelectGroup").options.add(new Option(group, group, false, true));
toggleNewGroupInput();
document.getElementById('burgInputGroup').value = '';
document.getElementById("burgInputGroup").value = "";
labelG.id = group;
iconG.id = group;
if (anchor) anchorG.id = group;
@ -336,9 +301,9 @@ function editBurg(id) {
}
// create new groups
document.getElementById('burgSelectGroup').options.add(new Option(group, group, false, true));
document.getElementById("burgSelectGroup").options.add(new Option(group, group, false, true));
toggleNewGroupInput();
document.getElementById('burgInputGroup').value = '';
document.getElementById("burgInputGroup").value = "";
addBurgsGroup(group);
moveBurgToGroup(id, group);
@ -346,13 +311,13 @@ function editBurg(id) {
function removeBurgsGroup() {
const group = elSelected.node().parentNode;
const basic = group.id === 'cities' || group.id === 'towns';
const basic = group.id === "cities" || group.id === "towns";
const burgsInGroup = [];
for (let i = 0; i < group.children.length; i++) {
burgsInGroup.push(+group.children[i].dataset.id);
}
const burgsToRemove = burgsInGroup.filter((b) => !(pack.burgs[b].capital || pack.burgs[b].lock));
const burgsToRemove = burgsInGroup.filter(b => !(pack.burgs[b].capital || pack.burgs[b].lock));
const capital = burgsToRemove.length < burgsInGroup.length;
alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${
@ -387,7 +352,7 @@ function editBurg(id) {
}
function changeName() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
pack.burgs[id].name = burgName.value;
elSelected.text(burgName.value);
}
@ -399,17 +364,17 @@ function editBurg(id) {
}
function changeType() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
pack.burgs[id].type = this.value;
}
function changeCulture() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
pack.burgs[id].culture = +this.value;
}
function generateNameCulture() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
const culture = pack.burgs[id].culture;
burgName.value = Names.getCulture(culture);
changeName();
@ -445,7 +410,7 @@ function editBurg(id) {
}
function updateBurgLockIcon() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
const b = pack.burgs[id];
if (b.lock) {
document.getElementById("burgLock").classList.remove("icon-lock-open");
@ -468,17 +433,17 @@ function editBurg(id) {
function editGroupLabelStyle() {
const g = elSelected.node().parentNode.id;
editStyle('labels', g);
editStyle("labels", g);
}
function editGroupIconStyle() {
const g = elSelected.node().parentNode.id;
editStyle('burgIcons', g);
editStyle("burgIcons", g);
}
function editGroupAnchorStyle() {
const g = elSelected.node().parentNode.id;
editStyle('anchors', g);
editStyle("anchors", g);
}
function updateMFCGFrame(burg) {
@ -527,12 +492,6 @@ function editBurg(id) {
document.getElementById("burgToggleMFCGMap").className = options.showMFCGMap ? "icon-map" : "icon-map-o";
}
function toggleMFCGMap() {
options.showMFCGMap = !options.showMFCGMap;
document.getElementById("mfcgPreviewSection").style.display = options.showMFCGMap ? "block" : "none";
document.getElementById("burgToggleMFCGMap").className = options.showMFCGMap ? "icon-map" : "icon-map-o";
}
function toggleRelocateBurg() {
const toggler = document.getElementById("toggleCells");
document.getElementById("burgRelocate").classList.toggle("pressed");
@ -557,16 +516,16 @@ function editBurg(id) {
const cells = pack.cells;
const point = d3.mouse(this);
const cell = findCell(point[0], point[1]);
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
const burg = pack.burgs[id];
if (cells.h[cell] < 20) {
tip('Cannot place burg into the water! Select a land cell', false, 'error');
tip("Cannot place burg into the water! Select a land cell", false, "error");
return;
}
if (cells.burg[cell] && cells.burg[cell] !== id) {
tip('There is already a burg in this cell. Please select a free cell', false, 'error');
tip("There is already a burg in this cell. Please select a free cell", false, "error");
return;
}
@ -574,7 +533,7 @@ function editBurg(id) {
const oldState = burg.state;
if (newState !== oldState && burg.capital) {
tip('Capital cannot be relocated into another state!', false, 'error');
tip("Capital cannot be relocated into another state!", false, "error");
return;
}
@ -593,10 +552,10 @@ function editBurg(id) {
.attr("y", y);
const anchor = anchors.select("use[data-id='" + id + "']");
if (anchor.size()) {
const size = anchor.attr('width');
const size = anchor.attr("width");
const xa = rn(x - size * 0.47, 2);
const ya = rn(y - size * 0.47, 2);
anchor.attr('transform', null).attr('x', xa).attr('y', ya);
anchor.attr("transform", null).attr("x", xa).attr("y", ya);
}
// change data
@ -612,7 +571,7 @@ function editBurg(id) {
}
function editBurgLegend() {
const id = elSelected.attr('data-id');
const id = elSelected.attr("data-id");
const name = elSelected.text();
editNotes("burg" + id, name);
}
@ -622,13 +581,8 @@ function editBurg(id) {
showBurgTemperatureGraph(id);
}
function showTemperatureGraph() {
const id = elSelected.attr("data-id");
showBurgTemperatureGraph(id);
}
function removeSelectedBurg() {
const id = +elSelected.attr('data-id');
const id = +elSelected.attr("data-id");
if (pack.burgs[id].capital) {
alertMessage.innerHTML = /* html */ `You cannot remove the burg as it is a state capital.<br /><br />
You can change the capital using Burgs Editor (shift + T)`;
@ -659,9 +613,10 @@ function editBurg(id) {
});
}
}
function closeBurgEditor() {
document.getElementById('burgRelocate').classList.remove('pressed');
burgLabels.selectAll('text').call(d3.drag().on('drag', null)).classed('draggable', false);
document.getElementById("burgRelocate").classList.remove("pressed");
burgLabels.selectAll("text").call(d3.drag().on("drag", null)).classed("draggable", false);
unselect();
}
}

View file

@ -1,11 +1,11 @@
'use strict';
"use strict";
function overviewBurgs() {
if (customization) return;
closeDialogs('#burgsOverview, .stable');
if (!layerIsOn('toggleIcons')) toggleIcons();
if (!layerIsOn('toggleLabels')) toggleLabels();
closeDialogs("#burgsOverview, .stable");
if (!layerIsOn("toggleIcons")) toggleIcons();
if (!layerIsOn("toggleLabels")) toggleLabels();
const body = document.getElementById('burgsBody');
const body = document.getElementById("burgsBody");
updateFilter();
updateLockAllIcon();
burgsOverviewAddLines();
@ -44,7 +44,7 @@ function overviewBurgs() {
}
function updateFilter() {
const stateFilter = document.getElementById('burgsFilterState');
const stateFilter = document.getElementById("burgsFilterState");
const selectedState = stateFilter.value || 1;
stateFilter.options.length = 0; // remove all options
stateFilter.options.add(new Option(`all`, -1, false, selectedState == -1));
@ -52,7 +52,7 @@ function overviewBurgs() {
const statesSorted = pack.states.filter(s => s.i && !s.removed).sort((a, b) => (a.name > b.name ? 1 : -1));
statesSorted.forEach(s => stateFilter.options.add(new Option(s.name, s.i, false, s.i == selectedState)));
const cultureFilter = document.getElementById('burgsFilterCulture');
const cultureFilter = document.getElementById("burgsFilterCulture");
const selectedCulture = cultureFilter.value || -1;
cultureFilter.options.length = 0; // remove all options
cultureFilter.options.add(new Option(`all`, -1, false, selectedCulture == -1));
@ -63,11 +63,11 @@ function overviewBurgs() {
// add line for each burg
function burgsOverviewAddLines() {
const selectedState = +document.getElementById('burgsFilterState').value;
const selectedCulture = +document.getElementById('burgsFilterCulture').value;
let filtered = pack.burgs.filter((b) => b.i && !b.removed); // all valid burgs
if (selectedState != -1) filtered = filtered.filter((b) => b.state === selectedState); // filtered by state
if (selectedCulture != -1) filtered = filtered.filter((b) => b.culture === selectedCulture); // filtered by culture
const selectedState = +document.getElementById("burgsFilterState").value;
const selectedCulture = +document.getElementById("burgsFilterCulture").value;
let filtered = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
if (selectedState != -1) filtered = filtered.filter(b => b.state === selectedState); // filtered by state
if (selectedCulture != -1) filtered = filtered.filter(b => b.culture === selectedCulture); // filtered by culture
body.innerHTML = "";
let lines = "",
@ -76,10 +76,10 @@ function overviewBurgs() {
for (const b of filtered) {
const population = b.population * populationRate * urbanization;
totalPopulation += population;
const type = b.capital && b.port ? 'a-capital-port' : b.capital ? 'c-capital' : b.port ? 'p-port' : 'z-burg';
const type = b.capital && b.port ? "a-capital-port" : b.capital ? "c-capital" : b.port ? "p-port" : "z-burg";
const state = pack.states[b.state].name;
const prov = pack.cells.province[b.cell];
const province = prov ? pack.provinces[prov].name : '';
const province = prov ? pack.provinces[prov].name : "";
const culture = pack.cultures[b.culture].name;
lines += /* html */ `<div
@ -113,7 +113,7 @@ function overviewBurgs() {
<span data-tip="Remove burg" class="icon-trash-empty"></span>
</div>`;
}
body.insertAdjacentHTML('beforeend', lines);
body.insertAdjacentHTML("beforeend", lines);
// update footer
burgsFooterBurgs.innerHTML = filtered.length;
@ -142,13 +142,13 @@ function overviewBurgs() {
}
function burgHighlightOn(event) {
if (!layerIsOn('toggleLabels')) toggleLabels();
if (!layerIsOn("toggleLabels")) toggleLabels();
const burg = +event.target.dataset.id;
burgLabels.select("[data-id='" + burg + "']").classed('drag', true);
burgLabels.select("[data-id='" + burg + "']").classed("drag", true);
}
function burgHighlightOff() {
burgLabels.selectAll('text.drag').classed('drag', false);
burgLabels.selectAll("text.drag").classed("drag", false);
}
function changeBurgName() {
@ -187,7 +187,7 @@ function overviewBurgs() {
this.value = si(this.value);
const population = [];
body.querySelectorAll(':scope > div').forEach((el) => population.push(+getInteger(el.dataset.population)));
body.querySelectorAll(":scope > div").forEach(el => population.push(+getInteger(el.dataset.population)));
burgsFooterPopulation.innerHTML = si(d3.mean(population));
}
@ -200,8 +200,8 @@ function overviewBurgs() {
function togglePortStatus() {
const burg = +this.parentNode.parentNode.dataset.id;
togglePort(burg);
if (this.classList.contains('inactive')) this.classList.remove('inactive');
else this.classList.add('inactive');
if (this.classList.contains("inactive")) this.classList.remove("inactive");
else this.classList.add("inactive");
}
function toggleBurgLockStatus() {
@ -258,9 +258,9 @@ function overviewBurgs() {
function enterAddBurgMode() {
if (this.classList.contains("pressed")) return exitAddBurgMode();
customization = 3;
this.classList.add('pressed');
tip('Click on the map to create a new burg. Hold Shift to add multiple', true, 'warn');
viewbox.style('cursor', 'crosshair').on('click', addBurgOnClick);
this.classList.add("pressed");
tip("Click on the map to create a new burg. Hold Shift to add multiple", true, "warn");
viewbox.style("cursor", "crosshair").on("click", addBurgOnClick);
}
function addBurgOnClick() {
@ -281,14 +281,14 @@ function overviewBurgs() {
customization = 0;
restoreDefaultEvents();
clearMainTip();
if (addBurgTool.classList.contains('pressed')) addBurgTool.classList.remove('pressed');
if (addNewBurg.classList.contains('pressed')) addNewBurg.classList.remove('pressed');
if (addBurgTool.classList.contains("pressed")) addBurgTool.classList.remove("pressed");
if (addNewBurg.classList.contains("pressed")) addNewBurg.classList.remove("pressed");
}
function showBurgsChart() {
// build hierarchy tree
const states = pack.states.map((s) => {
const color = s.color ? s.color : '#ccc';
const states = pack.states.map(s => {
const color = s.color ? s.color : "#ccc";
const name = s.fullName ? s.fullName : s.name;
return {id: s.i, state: s.i ? 0 : null, color, name};
});
@ -353,22 +353,22 @@ function overviewBurgs() {
.on("click", d => zoomTo(d.data.x, d.data.y, 8, 2000));
function showInfo(ev, d) {
d3.select(ev.target).transition().duration(1500).attr('stroke', '#c13119');
d3.select(ev.target).transition().duration(1500).attr("stroke", "#c13119");
const name = d.data.name;
const parent = d.parent.data.name;
const population = si(d.value * populationRate * urbanization);
burgsInfo.innerHTML = /* html */ `${name}. ${parent}. Population: ${population}`;
burgHighlightOn(ev);
tip('Click to zoom into view');
tip("Click to zoom into view");
}
function hideInfo(ev) {
burgHighlightOff(ev);
if (!document.getElementById('burgsInfo')) return;
burgsInfo.innerHTML = '&#8205;';
d3.select(ev.target).transition().attr('stroke', null);
tip('');
if (!document.getElementById("burgsInfo")) return;
burgsInfo.innerHTML = "&#8205;";
d3.select(ev.target).transition().attr("stroke", null);
tip("");
}
function updateChart() {
@ -386,8 +386,8 @@ function overviewBurgs() {
});
const getParentData = () => {
const states = pack.states.map((s) => {
const color = s.color ? s.color : '#ccc';
const states = pack.states.map(s => {
const color = s.color ? s.color : "#ccc";
const name = s.fullName ? s.fullName : s.name;
return {id: s.i, parent: s.i ? 0 : null, color, name};
});
@ -458,9 +458,9 @@ function overviewBurgs() {
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
valid.forEach((b) => {
data += b.i + ',';
data += b.name + ',';
valid.forEach(b => {
data += b.i + ",";
data += b.name + ",";
const province = pack.cells.province[b.cell];
data += province ? pack.provinces[province].name + "," : ",";
data += province ? pack.provinces[province].fullName + "," : ",";
@ -487,7 +487,7 @@ function overviewBurgs() {
data += "\n";
});
const name = getFileName('Burgs') + '.csv';
const name = getFileName("Burgs") + ".csv";
downloadFile(data, name);
}
@ -567,7 +567,7 @@ function overviewBurgs() {
}
function removeAllBurgs() {
pack.burgs.filter((b) => b.i && !(b.capital || b.lock)).forEach((b) => removeBurg(b.i));
pack.burgs.filter(b => b.i && !(b.capital || b.lock)).forEach(b => removeBurg(b.i));
burgsOverviewAddLines();
}

View file

@ -1,8 +1,8 @@
'use strict';
"use strict";
function editCoastline(node = d3.event.target) {
if (customization) return;
closeDialogs('.stable');
if (layerIsOn('toggleCells')) toggleCells();
closeDialogs(".stable");
if (layerIsOn("toggleCells")) toggleCells();
$("#coastlineEditor").dialog({
title: "Edit Coastline",
@ -11,26 +11,26 @@ function editCoastline(node = d3.event.target) {
close: closeCoastlineEditor
});
debug.append('g').attr('id', 'vertices');
debug.append("g").attr("id", "vertices");
elSelected = d3.select(node);
selectCoastlineGroup(node);
drawCoastlineVertices();
viewbox.on('touchmove mousemove', null);
viewbox.on("touchmove mousemove", null);
if (modules.editCoastline) return;
modules.editCoastline = true;
// add listeners
document.getElementById('coastlineGroupsShow').addEventListener('click', showGroupSection);
document.getElementById('coastlineGroup').addEventListener('change', changeCoastlineGroup);
document.getElementById('coastlineGroupAdd').addEventListener('click', toggleNewGroupInput);
document.getElementById('coastlineGroupName').addEventListener('change', createNewGroup);
document.getElementById('coastlineGroupRemove').addEventListener('click', removeCoastlineGroup);
document.getElementById('coastlineGroupsHide').addEventListener('click', hideGroupSection);
document.getElementById('coastlineEditStyle').addEventListener('click', editGroupStyle);
document.getElementById("coastlineGroupsShow").addEventListener("click", showGroupSection);
document.getElementById("coastlineGroup").addEventListener("change", changeCoastlineGroup);
document.getElementById("coastlineGroupAdd").addEventListener("click", toggleNewGroupInput);
document.getElementById("coastlineGroupName").addEventListener("change", createNewGroup);
document.getElementById("coastlineGroupRemove").addEventListener("click", removeCoastlineGroup);
document.getElementById("coastlineGroupsHide").addEventListener("click", hideGroupSection);
document.getElementById("coastlineEditStyle").addEventListener("click", editGroupStyle);
function drawCoastlineVertices() {
const f = +elSelected.attr('data-f'); // feature id
const f = +elSelected.attr("data-f"); // feature id
const v = pack.features[f].vertices; // coastline outer vertices
const l = pack.cells.i.length;
@ -77,7 +77,7 @@ function editCoastline(node = d3.event.target) {
function redrawCoastline() {
lineGen.curve(d3.curveBasisClosed);
const f = +elSelected.attr('data-f');
const f = +elSelected.attr("data-f");
const vertices = pack.features[f].vertices;
const points = clipPoly(
vertices.map(v => pack.vertices.p[v]),
@ -107,7 +107,7 @@ function editCoastline(node = d3.event.target) {
function selectCoastlineGroup(node) {
const group = node.parentNode.id;
const select = document.getElementById('coastlineGroup');
const select = document.getElementById("coastlineGroup");
select.options.length = 0; // remove all options
coastline.selectAll("g").each(function () {
@ -120,13 +120,13 @@ function editCoastline(node = d3.event.target) {
}
function toggleNewGroupInput() {
if (coastlineGroupName.style.display === 'none') {
coastlineGroupName.style.display = 'inline-block';
if (coastlineGroupName.style.display === "none") {
coastlineGroupName.style.display = "inline-block";
coastlineGroupName.focus();
coastlineGroup.style.display = 'none';
coastlineGroup.style.display = "none";
} else {
coastlineGroupName.style.display = 'none';
coastlineGroup.style.display = 'inline-block';
coastlineGroupName.style.display = "none";
coastlineGroup.style.display = "inline-block";
}
}
@ -141,42 +141,42 @@ function editCoastline(node = d3.event.target) {
.replace(/[^\w\s]/gi, "");
if (document.getElementById(group)) {
tip('Element with this id already exists. Please provide a unique name', false, 'error');
tip("Element with this id already exists. Please provide a unique name", false, "error");
return;
}
if (Number.isFinite(+group.charAt(0))) {
tip('Group name should start with a letter', false, 'error');
tip("Group name should start with a letter", false, "error");
return;
}
// just rename if only 1 element left
const oldGroup = elSelected.node().parentNode;
const basic = ['sea_island', 'lake_island'].includes(oldGroup.id);
const basic = ["sea_island", "lake_island"].includes(oldGroup.id);
if (!basic && oldGroup.childElementCount === 1) {
document.getElementById('coastlineGroup').selectedOptions[0].remove();
document.getElementById('coastlineGroup').options.add(new Option(group, group, false, true));
document.getElementById("coastlineGroup").selectedOptions[0].remove();
document.getElementById("coastlineGroup").options.add(new Option(group, group, false, true));
oldGroup.id = group;
toggleNewGroupInput();
document.getElementById('coastlineGroupName').value = '';
document.getElementById("coastlineGroupName").value = "";
return;
}
// create a new group
const newGroup = elSelected.node().parentNode.cloneNode(false);
document.getElementById('coastline').appendChild(newGroup);
document.getElementById("coastline").appendChild(newGroup);
newGroup.id = group;
document.getElementById('coastlineGroup').options.add(new Option(group, group, false, true));
document.getElementById("coastlineGroup").options.add(new Option(group, group, false, true));
document.getElementById(group).appendChild(elSelected.node());
toggleNewGroupInput();
document.getElementById('coastlineGroupName').value = '';
document.getElementById("coastlineGroupName").value = "";
}
function removeCoastlineGroup() {
const group = elSelected.node().parentNode.id;
if (['sea_island', 'lake_island'].includes(group)) {
tip('This is one of the default groups, it cannot be removed', false, 'error');
if (["sea_island", "lake_island"].includes(group)) {
tip("This is one of the default groups, it cannot be removed", false, "error");
return;
}
@ -204,16 +204,15 @@ function editCoastline(node = d3.event.target) {
}
}
});
confirmationDialog({title: 'Remove coastline group', message, confirm: 'Remove', onConfirm});
}
function editGroupStyle() {
const g = elSelected.node().parentNode.id;
editStyle('coastline', g);
editStyle("coastline", g);
}
function closeCoastlineEditor() {
debug.select('#vertices').remove();
debug.select("#vertices").remove();
unselect();
}
}

View file

@ -1,14 +1,14 @@
'use strict';
"use strict";
function editEmblem(type, id, el) {
if (customization) return;
if (!id && d3.event) defineEmblemData(d3.event);
emblems.selectAll('use').call(d3.drag().on('drag', dragEmblem)).classed('draggable', true);
emblems.selectAll("use").call(d3.drag().on("drag", dragEmblem)).classed("draggable", true);
const emblemStates = document.getElementById('emblemStates');
const emblemProvinces = document.getElementById('emblemProvinces');
const emblemBurgs = document.getElementById('emblemBurgs');
const emblemShapeSelector = document.getElementById('emblemShapeSelector');
const emblemStates = document.getElementById("emblemStates");
const emblemProvinces = document.getElementById("emblemProvinces");
const emblemBurgs = document.getElementById("emblemBurgs");
const emblemShapeSelector = document.getElementById("emblemShapeSelector");
updateElementSelectors(type, id, el);
@ -26,21 +26,21 @@ function editEmblem(type, id, el) {
emblemProvinces.oninput = selectProvince;
emblemBurgs.oninput = selectBurg;
emblemShapeSelector.oninput = changeShape;
document.getElementById('emblemSizeSlider').oninput = changeSize;
document.getElementById('emblemSizeNumber').oninput = changeSize;
document.getElementById('emblemsRegenerate').onclick = regenerate;
document.getElementById('emblemsArmoria').onclick = openInArmoria;
document.getElementById('emblemsUpload').onclick = toggleUpload;
document.getElementById('emblemsUploadImage').onclick = () => imageToLoad.click();
document.getElementById('emblemsUploadSVG').onclick = () => svgToLoad.click();
document.getElementById('imageToLoad').onchange = () => uploadImage('image');
document.getElementById('svgToLoad').onchange = () => uploadImage('svg');
document.getElementById('emblemsDownload').onclick = toggleDownload;
document.getElementById('emblemsDownloadSVG').onclick = () => download('svg');
document.getElementById('emblemsDownloadPNG').onclick = () => download('png');
document.getElementById('emblemsDownloadJPG').onclick = () => download('jpeg');
document.getElementById('emblemsGallery').onclick = downloadGallery;
document.getElementById('emblemsFocus').onclick = showArea;
document.getElementById("emblemSizeSlider").oninput = changeSize;
document.getElementById("emblemSizeNumber").oninput = changeSize;
document.getElementById("emblemsRegenerate").onclick = regenerate;
document.getElementById("emblemsArmoria").onclick = openInArmoria;
document.getElementById("emblemsUpload").onclick = toggleUpload;
document.getElementById("emblemsUploadImage").onclick = () => emblemImageToLoad.click();
document.getElementById("emblemsUploadSVG").onclick = () => emblemSVGToLoad.click();
document.getElementById("emblemImageToLoad").onchange = () => upload("image");
document.getElementById("emblemSVGToLoad").onchange = () => upload("svg");
document.getElementById("emblemsDownload").onclick = toggleDownload;
document.getElementById("emblemsDownloadSVG").onclick = () => download("svg");
document.getElementById("emblemsDownloadPNG").onclick = () => download("png");
document.getElementById("emblemsDownloadJPG").onclick = () => download("jpeg");
document.getElementById("emblemsGallery").onclick = downloadGallery;
document.getElementById("emblemsFocus").onclick = showArea;
function defineEmblemData(e) {
const parent = e.target.parentNode;
@ -57,9 +57,9 @@ function editEmblem(type, id, el) {
burg = 0;
// set active type
emblemStates.parentElement.className = type === 'state' ? 'active' : '';
emblemProvinces.parentElement.className = type === 'province' ? 'active' : '';
emblemBurgs.parentElement.className = type === 'burg' ? 'active' : '';
emblemStates.parentElement.className = type === "state" ? "active" : "";
emblemProvinces.parentElement.className = type === "province" ? "active" : "";
emblemBurgs.parentElement.className = type === "burg" ? "active" : "";
// define selected values
if (type === "state") state = el.i;
@ -72,19 +72,19 @@ function editEmblem(type, id, el) {
state = el.state;
}
const validBurgs = pack.burgs.filter((burg) => burg.i && !burg.removed && burg.coa);
const validBurgs = pack.burgs.filter(burg => burg.i && !burg.removed && burg.coa);
// update option list and select actual values
emblemStates.options.length = 0;
const neutralBurgs = validBurgs.filter((burg) => !burg.state);
const neutralBurgs = validBurgs.filter(burg => !burg.state);
if (neutralBurgs.length) emblemStates.options.add(new Option(pack.states[0].name, 0, false, !state));
const stateList = pack.states.filter((state) => state.i && !state.removed);
stateList.forEach((s) => emblemStates.options.add(new Option(s.name, s.i, false, s.i === state)));
const stateList = pack.states.filter(state => state.i && !state.removed);
stateList.forEach(s => emblemStates.options.add(new Option(s.name, s.i, false, s.i === state)));
emblemProvinces.options.length = 0;
emblemProvinces.options.add(new Option('', 0, false, !province));
const provinceList = pack.provinces.filter((province) => !province.removed && province.state === state);
provinceList.forEach((p) => emblemProvinces.options.add(new Option(p.name, p.i, false, p.i === province)));
emblemProvinces.options.add(new Option("", 0, false, !province));
const provinceList = pack.provinces.filter(province => !province.removed && province.state === state);
provinceList.forEach(p => emblemProvinces.options.add(new Option(p.name, p.i, false, p.i === province)));
emblemBurgs.options.length = 0;
emblemBurgs.options.add(new Option("", 0, false, !burg));
@ -98,33 +98,33 @@ function editEmblem(type, id, el) {
function updateEmblemData(type, id, el) {
if (!el.coa) return;
document.getElementById('emblemImage').setAttribute('href', '#' + id);
document.getElementById("emblemImage").setAttribute("href", "#" + id);
let name = el.fullName || el.name;
if (type === 'burg') name = 'Burg of ' + name;
document.getElementById('emblemArmiger').innerText = name;
if (type === "burg") name = "Burg of " + name;
document.getElementById("emblemArmiger").innerText = name;
if (el.coa === 'custom') emblemShapeSelector.disabled = true;
if (el.coa === "custom") emblemShapeSelector.disabled = true;
else {
emblemShapeSelector.disabled = false;
emblemShapeSelector.value = el.coa.shield;
}
const size = el.coaSize || 1;
document.getElementById('emblemSizeSlider').value = size;
document.getElementById('emblemSizeNumber').value = size;
document.getElementById("emblemSizeSlider").value = size;
document.getElementById("emblemSizeNumber").value = size;
}
function selectState() {
const state = +this.value;
if (state) {
type = 'state';
type = "state";
el = pack.states[state];
id = "stateCOA" + state;
} else {
// select neutral burg if state is changed to Neutrals
const neutralBurgs = pack.burgs.filter((burg) => burg.i && !burg.removed && !burg.state);
const neutralBurgs = pack.burgs.filter(burg => burg.i && !burg.removed && !burg.state);
if (!neutralBurgs.length) return;
type = 'burg';
type = "burg";
el = neutralBurgs[0];
id = "burgCOA" + neutralBurgs[0].i;
}
@ -135,13 +135,13 @@ function editEmblem(type, id, el) {
const province = +this.value;
if (province) {
type = 'province';
type = "province";
el = pack.provinces[province];
id = "provinceCOA" + province;
} else {
// select state if province is changed to null value
const state = +emblemStates.value;
type = 'state';
type = "state";
el = pack.states[state];
id = "stateCOA" + state;
}
@ -151,7 +151,7 @@ function editEmblem(type, id, el) {
function selectBurg() {
const burg = +this.value;
type = 'burg';
type = "burg";
el = pack.burgs[burg];
id = "burgCOA" + burg;
updateElementSelectors(type, id, el);
@ -193,8 +193,8 @@ function editEmblem(type, id, el) {
function regenerate() {
let parent = null;
if (type === 'province') parent = pack.states[el.state];
else if (type === 'burg') {
if (type === "province") parent = pack.states[el.state];
else if (type === "burg") {
const province = pack.cells.province[el.cell];
parent = province ? pack.provinces[province] : pack.states[el.state];
}
@ -211,57 +211,64 @@ function editEmblem(type, id, el) {
}
function openInArmoria() {
const coa = el.coa && el.coa !== 'custom' ? el.coa : {t1: 'sable'};
const json = JSON.stringify(coa).replaceAll('#', '%23');
const coa = el.coa && el.coa !== "custom" ? el.coa : {t1: "sable"};
const json = JSON.stringify(coa).replaceAll("#", "%23");
const url = `https://azgaar.github.io/Armoria/?coa=${json}&from=FMG`;
openURL(url);
}
function toggleUpload() {
document.getElementById('emblemDownloadControl').classList.add('hidden');
const buttons = document.getElementById('emblemUploadControl');
buttons.classList.toggle('hidden');
document.getElementById("emblemDownloadControl").classList.add("hidden");
const buttons = document.getElementById("emblemUploadControl");
buttons.classList.toggle("hidden");
}
function uploadImage(type) {
const input = type === 'image' ? document.getElementById('imageToLoad') : document.getElementById('svgToLoad');
function upload(type) {
const input = type === "image" ? document.getElementById("emblemImageToLoad") : document.getElementById("emblemSVGToLoad");
const file = input.files[0];
input.value = '';
input.value = "";
if (file.size > 500000) return tip(`File is too big, please optimize file size up to 500kB and re-upload. Recommended size is 200x200 px and up to 100kB`, true, 'error', 5000);
if (file.size > 500000) {
tip(`File is too big, please optimize file size up to 500kB and re-upload. Recommended size is 200x200 px and up to 100kB`, true, "error", 5000);
return;
}
const reader = new FileReader();
reader.onload = function (readerEvent) {
const result = readerEvent.target.result;
const defs = document.getElementById('defs-emblems');
const defs = document.getElementById("defs-emblems");
const coa = document.getElementById(id); // old emblem
if (type === 'image') {
if (type === "image") {
const svg = `<svg id="${id}" xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"><image x="0" y="0" width="200" height="200" href="${result}"/></svg>`;
defs.insertAdjacentHTML('beforeend', svg);
defs.insertAdjacentHTML("beforeend", svg);
} else {
const el = document.createElement('html');
const el = document.createElement("html");
el.innerHTML = result;
// remove sodipodi and inkscape attributes
el.querySelectorAll('*').forEach((el) => {
el.querySelectorAll("*").forEach(el => {
const attributes = el.getAttributeNames();
attributes.forEach((attr) => {
if (attr.includes('inkscape') || attr.includes('sodipodi')) el.removeAttribute(attr);
attributes.forEach(attr => {
if (attr.includes("inkscape") || attr.includes("sodipodi")) el.removeAttribute(attr);
});
});
const svg = el.querySelector('svg');
if (!svg) return tip('The file should be prepated for load to FMG. Please use Armoria or other relevant tools', false, 'error');
const svg = el.querySelector("svg");
if (!svg) {
tip("The file should be prepated for load to FMG. Please use Armoria or other relevant tools", false, "error");
return;
}
const newEmblem = defs.appendChild(svg);
newEmblem.id = id;
newEmblem.setAttribute('width', 200);
newEmblem.setAttribute('height', 200);
newEmblem.setAttribute("width", 200);
newEmblem.setAttribute("height", 200);
}
if (coa) coa.remove(); // remove old emblem
el.coa = 'custom';
el.coa = "custom";
emblemShapeSelector.disabled = true;
};
@ -270,17 +277,17 @@ function editEmblem(type, id, el) {
}
function toggleDownload() {
document.getElementById('emblemUploadControl').classList.add('hidden');
const buttons = document.getElementById('emblemDownloadControl');
buttons.classList.toggle('hidden');
document.getElementById("emblemUploadControl").classList.add("hidden");
const buttons = document.getElementById("emblemDownloadControl");
buttons.classList.toggle("hidden");
}
async function download(format) {
const coa = document.getElementById(id);
const size = +emblemsDownloadSize.value;
const url = await getURL(coa, size);
const link = document.createElement('a');
link.download = getFileName(`Emblem ${el.fullName || el.name}`) + '.' + format;
const link = document.createElement("a");
link.download = getFileName(`Emblem ${el.fullName || el.name}`) + "." + format;
if (format === "svg") downloadSVG(url, link);
else downloadRaster(format, url, link, size);
@ -293,8 +300,8 @@ function editEmblem(type, id, el) {
}
function downloadRaster(format, url, link, size) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = size;
canvas.height = size;
@ -329,10 +336,10 @@ function editEmblem(type, id, el) {
}
async function downloadGallery() {
const name = getFileName('Emblems Gallery');
const validStates = pack.states.filter((s) => s.i && !s.removed && s.coa);
const validProvinces = pack.provinces.filter((p) => p.i && !p.removed && p.coa);
const validBurgs = pack.burgs.filter((b) => b.i && !b.removed && b.coa);
const name = getFileName("Emblems Gallery");
const validStates = pack.states.filter(s => s.i && !s.removed && s.coa);
const validProvinces = pack.provinces.filter(p => p.i && !p.removed && p.coa);
const validBurgs = pack.burgs.filter(b => b.i && !b.removed && b.coa);
await renderAllEmblems(validStates, validProvinces, validBurgs);
runDownload();
@ -473,14 +480,14 @@ function editEmblem(type, id, el) {
}
async function renderAllEmblems(states, provinces, burgs) {
tip('Preparing for download...', true, 'warn');
tip("Preparing for download...", true, "warn");
const statePromises = states.map(state => COArenderer.trigger("stateCOA" + state.i, state.coa));
const provincePromises = provinces.map(province => COArenderer.trigger("provinceCOA" + province.i, province.coa));
const burgPromises = burgs.map(burg => COArenderer.trigger("burgCOA" + burg.i, burg.coa));
const promises = [...statePromises, ...provincePromises, ...burgPromises];
return Promise.allSettled(promises).then((res) => clearMainTip());
return Promise.allSettled(promises).then(res => clearMainTip());
}
function dragEmblem() {
@ -495,6 +502,6 @@ function editEmblem(type, id, el) {
}
function closeEmblemEditor() {
emblems.selectAll('use').call(d3.drag().on('drag', null)).attr('class', null);
emblems.selectAll("use").call(d3.drag().on("drag", null)).attr("class", null);
}
}

View file

@ -172,8 +172,3 @@ function closeAllDialogs() {
closeDialogs();
hideOptions();
}
function closeAllDialogs() {
closeDialogs();
hideOptions();
}

View file

@ -1,15 +1,15 @@
'use strict';
"use strict";
function editIce() {
if (customization) return;
closeDialogs('.stable');
if (!layerIsOn('toggleIce')) toggleIce();
closeDialogs(".stable");
if (!layerIsOn("toggleIce")) toggleIce();
elSelected = d3.select(d3.event.target);
const type = elSelected.attr('type') ? 'Glacier' : 'Iceberg';
document.getElementById('iceRandomize').style.display = type === 'Glacier' ? 'none' : 'inline-block';
document.getElementById('iceSize').style.display = type === 'Glacier' ? 'none' : 'inline-block';
if (type === 'Iceberg') document.getElementById('iceSize').value = +elSelected.attr('size');
ice.selectAll('*').classed('draggable', true).call(d3.drag().on('drag', dragElement));
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
document.getElementById("iceRandomize").style.display = type === "Glacier" ? "none" : "inline-block";
document.getElementById("iceSize").style.display = type === "Glacier" ? "none" : "inline-block";
if (type === "Iceberg") document.getElementById("iceSize").value = +elSelected.attr("size");
ice.selectAll("*").classed("draggable", true).call(d3.drag().on("drag", dragElement));
$("#iceEditor").dialog({
title: "Edit " + type,
@ -22,11 +22,11 @@ function editIce() {
modules.editIce = true;
// add listeners
document.getElementById('iceEditStyle').addEventListener('click', () => editStyle('ice'));
document.getElementById('iceRandomize').addEventListener('click', randomizeShape);
document.getElementById('iceSize').addEventListener('input', changeSize);
document.getElementById('iceNew').addEventListener('click', toggleAdd);
document.getElementById('iceRemove').addEventListener('click', removeIce);
document.getElementById("iceEditStyle").addEventListener("click", () => editStyle("ice"));
document.getElementById("iceRandomize").addEventListener("click", randomizeShape);
document.getElementById("iceSize").addEventListener("input", changeSize);
document.getElementById("iceNew").addEventListener("click", toggleAdd);
document.getElementById("iceRemove").addEventListener("click", removeIce);
function randomizeShape() {
const c = grid.points[+elSelected.attr("cell")];
@ -49,18 +49,18 @@ function editIce() {
while (flat.length) pairs.push(flat.splice(0, 2));
const poly = pairs.map(p => [(p[0] - c[0]) / s, (p[1] - c[1]) / s]);
const size = +this.value;
const points = poly.map((p) => [rn(c[0] + p[0] * size, 2), rn(c[1] + p[1] * size, 2)]);
elSelected.attr('points', points).attr('size', size);
const points = poly.map(p => [rn(c[0] + p[0] * size, 2), rn(c[1] + p[1] * size, 2)]);
elSelected.attr("points", points).attr("size", size);
}
function toggleAdd() {
document.getElementById('iceNew').classList.toggle('pressed');
if (document.getElementById('iceNew').classList.contains('pressed')) {
viewbox.style('cursor', 'crosshair').on('click', addIcebergOnClick);
tip('Click on map to create an iceberg. Hold Shift to add multiple', true);
document.getElementById("iceNew").classList.toggle("pressed");
if (document.getElementById("iceNew").classList.contains("pressed")) {
viewbox.style("cursor", "crosshair").on("click", addIcebergOnClick);
tip("Click on map to create an iceberg. Hold Shift to add multiple", true);
} else {
clearMainTip();
viewbox.on('click', clicked).style('cursor', 'default');
viewbox.on("click", clicked).style("cursor", "default");
}
}
@ -68,7 +68,7 @@ function editIce() {
const [x, y] = d3.mouse(this);
const i = findGridCell(x, y, grid);
const c = grid.points[i];
const s = +document.getElementById('iceSize').value;
const s = +document.getElementById("iceSize").value;
const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) / s) | 0, (p[1] + (c[1] - p[1]) / s) | 0]);
const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", s);
@ -108,9 +108,9 @@ function editIce() {
}
function closeEditor() {
ice.selectAll('*').classed('draggable', false).call(d3.drag().on('drag', null));
ice.selectAll("*").classed("draggable", false).call(d3.drag().on("drag", null));
clearMainTip();
iceNew.classList.remove('pressed');
iceNew.classList.remove("pressed");
unselect();
}
}

View file

@ -1,14 +1,14 @@
'use strict';
"use strict";
function editLabel() {
if (customization) return;
closeDialogs();
if (!layerIsOn('toggleLabels')) toggleLabels();
if (!layerIsOn("toggleLabels")) toggleLabels();
const tspan = d3.event.target;
const textPath = tspan.parentNode;
const text = textPath.parentNode;
elSelected = d3.select(text).call(d3.drag().on('start', dragLabel)).classed('draggable', true);
viewbox.on('touchmove mousemove', showEditorTips);
elSelected = d3.select(text).call(d3.drag().on("start", dragLabel)).classed("draggable", true);
viewbox.on("touchmove mousemove", showEditorTips);
$("#labelEditor").dialog({
title: "Edit Label",
@ -26,28 +26,28 @@ function editLabel() {
modules.editLabel = true;
// add listeners
document.getElementById('labelGroupShow').addEventListener('click', showGroupSection);
document.getElementById('labelGroupHide').addEventListener('click', hideGroupSection);
document.getElementById('labelGroupSelect').addEventListener('click', changeGroup);
document.getElementById('labelGroupInput').addEventListener('change', createNewGroup);
document.getElementById('labelGroupNew').addEventListener('click', toggleNewGroupInput);
document.getElementById('labelGroupRemove').addEventListener('click', removeLabelsGroup);
document.getElementById("labelGroupShow").addEventListener("click", showGroupSection);
document.getElementById("labelGroupHide").addEventListener("click", hideGroupSection);
document.getElementById("labelGroupSelect").addEventListener("click", changeGroup);
document.getElementById("labelGroupInput").addEventListener("change", createNewGroup);
document.getElementById("labelGroupNew").addEventListener("click", toggleNewGroupInput);
document.getElementById("labelGroupRemove").addEventListener("click", removeLabelsGroup);
document.getElementById('labelTextShow').addEventListener('click', showTextSection);
document.getElementById('labelTextHide').addEventListener('click', hideTextSection);
document.getElementById('labelText').addEventListener('input', changeText);
document.getElementById('labelTextRandom').addEventListener('click', generateRandomName);
document.getElementById("labelTextShow").addEventListener("click", showTextSection);
document.getElementById("labelTextHide").addEventListener("click", hideTextSection);
document.getElementById("labelText").addEventListener("input", changeText);
document.getElementById("labelTextRandom").addEventListener("click", generateRandomName);
document.getElementById('labelEditStyle').addEventListener('click', editGroupStyle);
document.getElementById("labelEditStyle").addEventListener("click", editGroupStyle);
document.getElementById('labelSizeShow').addEventListener('click', showSizeSection);
document.getElementById('labelSizeHide').addEventListener('click', hideSizeSection);
document.getElementById('labelStartOffset').addEventListener('input', changeStartOffset);
document.getElementById('labelRelativeSize').addEventListener('input', changeRelativeSize);
document.getElementById("labelSizeShow").addEventListener("click", showSizeSection);
document.getElementById("labelSizeHide").addEventListener("click", hideSizeSection);
document.getElementById("labelStartOffset").addEventListener("input", changeStartOffset);
document.getElementById("labelRelativeSize").addEventListener("input", changeRelativeSize);
document.getElementById('labelAlign').addEventListener('click', editLabelAlign);
document.getElementById('labelLegend').addEventListener('click', editLabelLegend);
document.getElementById('labelRemoveSingle').addEventListener('click', removeLabel);
document.getElementById("labelAlign").addEventListener("click", editLabelAlign);
document.getElementById("labelLegend").addEventListener("click", editLabelLegend);
document.getElementById("labelRemoveSingle").addEventListener("click", removeLabel);
function showEditorTips() {
showMainTip();
@ -78,16 +78,16 @@ function editLabel() {
}
function updateValues(textPath) {
document.getElementById('labelText').value = [...textPath.querySelectorAll('tspan')].map((tspan) => tspan.textContent).join('|');
document.getElementById('labelStartOffset').value = parseFloat(textPath.getAttribute('startOffset'));
document.getElementById('labelRelativeSize').value = parseFloat(textPath.getAttribute('font-size'));
document.getElementById("labelText").value = [...textPath.querySelectorAll("tspan")].map(tspan => tspan.textContent).join("|");
document.getElementById("labelStartOffset").value = parseFloat(textPath.getAttribute("startOffset"));
document.getElementById("labelRelativeSize").value = parseFloat(textPath.getAttribute("font-size"));
}
function drawControlPointsAndLine() {
debug.select('#controlPoints').remove();
debug.append('g').attr('id', 'controlPoints').attr('transform', elSelected.attr('transform'));
const path = document.getElementById('textPath_' + elSelected.attr('id'));
debug.select('#controlPoints').append('path').attr('d', path.getAttribute('d')).on('click', addInterimControlPoint);
debug.select("#controlPoints").remove();
debug.append("g").attr("id", "controlPoints").attr("transform", elSelected.attr("transform"));
const path = document.getElementById("textPath_" + elSelected.attr("id"));
debug.select("#controlPoints").append("path").attr("d", path.getAttribute("d")).on("click", addInterimControlPoint);
const l = path.getTotalLength();
if (!l) return;
const increment = l / Math.max(Math.ceil(l / 200), 2);
@ -109,13 +109,13 @@ function editLabel() {
}
function dragControlPoint() {
this.setAttribute('cx', d3.event.x);
this.setAttribute('cy', d3.event.y);
this.setAttribute("cx", d3.event.x);
this.setAttribute("cy", d3.event.y);
redrawLabelPath();
}
function redrawLabelPath() {
const path = document.getElementById('textPath_' + elSelected.attr('id'));
const path = document.getElementById("textPath_" + elSelected.attr("id"));
lineGen.curve(d3.curveBundle.beta(1));
const points = [];
debug
@ -125,8 +125,8 @@ function editLabel() {
points.push([this.getAttribute("cx"), this.getAttribute("cy")]);
});
const d = round(lineGen(points));
path.setAttribute('d', d);
debug.select('#controlPoints > path').attr('d', d);
path.setAttribute("d", d);
debug.select("#controlPoints > path").attr("d", d);
}
function clickControlPoint() {
@ -202,10 +202,10 @@ function editLabel() {
}
function toggleNewGroupInput() {
if (labelGroupInput.style.display === 'none') {
labelGroupInput.style.display = 'inline-block';
if (labelGroupInput.style.display === "none") {
labelGroupInput.style.display = "inline-block";
labelGroupInput.focus();
labelGroupSelect.style.display = 'none';
labelGroupSelect.style.display = "none";
} else {
labelGroupInput.style.display = "none";
labelGroupSelect.style.display = "inline-block";
@ -223,39 +223,39 @@ function editLabel() {
.replace(/[^\w\s]/gi, "");
if (document.getElementById(group)) {
tip('Element with this id already exists. Please provide a unique name', false, 'error');
tip("Element with this id already exists. Please provide a unique name", false, "error");
return;
}
if (Number.isFinite(+group.charAt(0))) {
tip('Group name should start with a letter', false, 'error');
tip("Group name should start with a letter", false, "error");
return;
}
// just rename if only 1 element left
const oldGroup = elSelected.node().parentNode;
if (oldGroup !== 'states' && oldGroup !== 'addedLabels' && oldGroup.childElementCount === 1) {
document.getElementById('labelGroupSelect').selectedOptions[0].remove();
document.getElementById('labelGroupSelect').options.add(new Option(group, group, false, true));
if (oldGroup !== "states" && oldGroup !== "addedLabels" && oldGroup.childElementCount === 1) {
document.getElementById("labelGroupSelect").selectedOptions[0].remove();
document.getElementById("labelGroupSelect").options.add(new Option(group, group, false, true));
oldGroup.id = group;
toggleNewGroupInput();
document.getElementById('labelGroupInput').value = '';
document.getElementById("labelGroupInput").value = "";
return;
}
const newGroup = elSelected.node().parentNode.cloneNode(false);
document.getElementById('labels').appendChild(newGroup);
document.getElementById("labels").appendChild(newGroup);
newGroup.id = group;
document.getElementById('labelGroupSelect').options.add(new Option(group, group, false, true));
document.getElementById("labelGroupSelect").options.add(new Option(group, group, false, true));
document.getElementById(group).appendChild(elSelected.node());
toggleNewGroupInput();
document.getElementById('labelGroupInput').value = '';
document.getElementById("labelGroupInput").value = "";
}
function removeLabelsGroup() {
const group = elSelected.node().parentNode.id;
const basic = group === 'states' || group === 'addedLabels';
const basic = group === "states" || group === "addedLabels";
const count = elSelected.node().parentNode.childElementCount;
alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${
basic ? "all elements in the group" : "the entire label group"
@ -300,12 +300,7 @@ function editLabel() {
const el = elSelected.select("textPath").node();
const example = d3.select(elSelected.node().parentNode).append("text").attr("x", 0).attr("x", 0).attr("font-size", el.getAttribute("font-size")).node();
function changeText() {
const input = document.getElementById('labelText').value;
const el = elSelected.select('textPath').node();
const example = d3.select(elSelected.node().parentNode).append('text').attr('x', 0).attr('x', 0).attr('font-size', el.getAttribute('font-size')).node();
const lines = input.split('|');
const lines = input.split("|");
const top = (lines.length - 1) / -2; // y offset
const inner = lines
.map((l, d) => {
@ -326,20 +321,20 @@ function editLabel() {
if (elSelected.attr("id").slice(0, 10) === "stateLabel") {
const id = +elSelected.attr("id").slice(10);
const culture = pack.states[id].culture;
name = Names.getState(Names.getCulture(culture, 4, 7, ''), culture);
name = Names.getState(Names.getCulture(culture, 4, 7, ""), culture);
} else {
const box = elSelected.node().getBBox();
const cell = findCell((box.x + box.width) / 2, (box.y + box.height) / 2);
const culture = pack.cells.culture[cell];
name = Names.getCulture(culture);
}
document.getElementById('labelText').value = name;
document.getElementById("labelText").value = name;
changeText();
}
function editGroupStyle() {
const g = elSelected.node().parentNode.id;
editStyle('labels', g);
editStyle("labels", g);
}
function showSizeSection() {
@ -353,13 +348,13 @@ function editLabel() {
}
function changeStartOffset() {
elSelected.select('textPath').attr('startOffset', this.value + '%');
tip('Label offset: ' + this.value + '%');
elSelected.select("textPath").attr("startOffset", this.value + "%");
tip("Label offset: " + this.value + "%");
}
function changeRelativeSize() {
elSelected.select('textPath').attr('font-size', this.value + '%');
tip('Label relative size: ' + this.value + '%');
elSelected.select("textPath").attr("font-size", this.value + "%");
tip("Label relative size: " + this.value + "%");
changeText();
}
@ -372,7 +367,7 @@ function editLabel() {
}
function editLabelLegend() {
const id = elSelected.attr('id');
const id = elSelected.attr("id");
const name = elSelected.text();
editNotes(id, name);
}
@ -397,8 +392,7 @@ function editLabel() {
}
function closeLabelEditor() {
debug.select('#controlPoints').remove();
debug.select("#controlPoints").remove();
unselect();
}
}
}

View file

@ -1,8 +1,8 @@
'use strict';
"use strict";
function editLake() {
if (customization) return;
closeDialogs('.stable');
if (layerIsOn('toggleCells')) toggleCells();
closeDialogs(".stable");
if (layerIsOn("toggleCells")) toggleCells();
$("#lakeEditor").dialog({
title: "Edit Lake",
@ -12,32 +12,32 @@ function editLake() {
});
const node = d3.event.target;
debug.append('g').attr('id', 'vertices');
debug.append("g").attr("id", "vertices");
elSelected = d3.select(node);
updateLakeValues();
selectLakeGroup(node);
drawLakeVertices();
viewbox.on('touchmove mousemove', null);
viewbox.on("touchmove mousemove", null);
if (modules.editLake) return;
modules.editLake = true;
// add listeners
document.getElementById('lakeName').addEventListener('input', changeName);
document.getElementById('lakeNameCulture').addEventListener('click', generateNameCulture);
document.getElementById('lakeNameRandom').addEventListener('click', generateNameRandom);
document.getElementById("lakeName").addEventListener("input", changeName);
document.getElementById("lakeNameCulture").addEventListener("click", generateNameCulture);
document.getElementById("lakeNameRandom").addEventListener("click", generateNameRandom);
document.getElementById('lakeGroup').addEventListener('change', changeLakeGroup);
document.getElementById('lakeGroupAdd').addEventListener('click', toggleNewGroupInput);
document.getElementById('lakeGroupName').addEventListener('change', createNewGroup);
document.getElementById('lakeGroupRemove').addEventListener('click', removeLakeGroup);
document.getElementById("lakeGroup").addEventListener("change", changeLakeGroup);
document.getElementById("lakeGroupAdd").addEventListener("click", toggleNewGroupInput);
document.getElementById("lakeGroupName").addEventListener("change", createNewGroup);
document.getElementById("lakeGroupRemove").addEventListener("click", removeLakeGroup);
document.getElementById('lakeEditStyle').addEventListener('click', editGroupStyle);
document.getElementById('lakeLegend').addEventListener('click', editLakeLegend);
document.getElementById("lakeEditStyle").addEventListener("click", editGroupStyle);
document.getElementById("lakeLegend").addEventListener("click", editLakeLegend);
function getLake() {
const lakeId = +elSelected.attr('data-f');
return pack.features.find((feature) => feature.i === lakeId);
const lakeId = +elSelected.attr("data-f");
return pack.features.find(feature => feature.i === lakeId);
}
function updateLakeValues() {
@ -51,21 +51,21 @@ function editLake() {
document.getElementById("lakeShoreLength").value =
si(length * distanceScaleInput.value) + " " + distanceUnitInput.value;
const lakeCells = Array.from(cells.i.filter((i) => cells.f[i] === l.i));
const heights = lakeCells.map((i) => cells.h[i]);
const lakeCells = Array.from(cells.i.filter(i => cells.f[i] === l.i));
const heights = lakeCells.map(i => cells.h[i]);
document.getElementById("lakeElevation").value = getHeight(l.height);
document.getElementById("lakeAverageDepth").value = getHeight(d3.mean(heights), "abs");
document.getElementById("lakeMaxDepth").value = getHeight(d3.min(heights), "abs");
document.getElementById('lakeFlux').value = l.flux;
document.getElementById('lakeEvaporation').value = l.evaporation;
document.getElementById("lakeFlux").value = l.flux;
document.getElementById("lakeEvaporation").value = l.evaporation;
const inlets = l.inlets && l.inlets.map((inlet) => pack.rivers.find((river) => river.i === inlet)?.name);
const outlet = l.outlet ? pack.rivers.find((river) => river.i === l.outlet)?.name : 'no';
document.getElementById('lakeInlets').value = inlets ? inlets.length : 'no';
document.getElementById('lakeInlets').title = inlets ? inlets.join(', ') : '';
document.getElementById('lakeOutlet').value = outlet;
const inlets = l.inlets && l.inlets.map(inlet => pack.rivers.find(river => river.i === inlet)?.name);
const outlet = l.outlet ? pack.rivers.find(river => river.i === l.outlet)?.name : "no";
document.getElementById("lakeInlets").value = inlets ? inlets.length : "no";
document.getElementById("lakeInlets").title = inlets ? inlets.join(", ") : "";
document.getElementById("lakeOutlet").value = outlet;
}
function drawLakeVertices() {
@ -114,7 +114,7 @@ function editLake() {
function redrawLake() {
lineGen.curve(d3.curveBasisClosed);
const feature = getLake();
const points = feature.vertices.map((v) => pack.vertices.p[v]);
const points = feature.vertices.map(v => pack.vertices.p[v]);
const d = round(lineGen(points));
elSelected.attr("d", d);
defs.select("mask#land > path#land_" + feature.i).attr("d", d); // update land mask
@ -139,7 +139,7 @@ function editLake() {
function selectLakeGroup(node) {
const group = node.parentNode.id;
const select = document.getElementById('lakeGroup');
const select = document.getElementById("lakeGroup");
select.options.length = 0; // remove all options
lakes.selectAll("g").each(function () {
@ -153,10 +153,10 @@ function editLake() {
}
function toggleNewGroupInput() {
if (lakeGroupName.style.display === 'none') {
lakeGroupName.style.display = 'inline-block';
if (lakeGroupName.style.display === "none") {
lakeGroupName.style.display = "inline-block";
lakeGroupName.focus();
lakeGroup.style.display = 'none';
lakeGroup.style.display = "none";
} else {
lakeGroupName.style.display = "none";
lakeGroup.style.display = "inline-block";
@ -174,42 +174,42 @@ function editLake() {
.replace(/[^\w\s]/gi, "");
if (document.getElementById(group)) {
tip('Element with this id already exists. Please provide a unique name', false, 'error');
tip("Element with this id already exists. Please provide a unique name", false, "error");
return;
}
if (Number.isFinite(+group.charAt(0))) {
tip('Group name should start with a letter', false, 'error');
tip("Group name should start with a letter", false, "error");
return;
}
// just rename if only 1 element left
const oldGroup = elSelected.node().parentNode;
const basic = ['freshwater', 'salt', 'sinkhole', 'frozen', 'lava', 'dry'].includes(oldGroup.id);
const basic = ["freshwater", "salt", "sinkhole", "frozen", "lava", "dry"].includes(oldGroup.id);
if (!basic && oldGroup.childElementCount === 1) {
document.getElementById('lakeGroup').selectedOptions[0].remove();
document.getElementById('lakeGroup').options.add(new Option(group, group, false, true));
document.getElementById("lakeGroup").selectedOptions[0].remove();
document.getElementById("lakeGroup").options.add(new Option(group, group, false, true));
oldGroup.id = group;
toggleNewGroupInput();
document.getElementById('lakeGroupName').value = '';
document.getElementById("lakeGroupName").value = "";
return;
}
// create a new group
const newGroup = elSelected.node().parentNode.cloneNode(false);
document.getElementById('lakes').appendChild(newGroup);
document.getElementById("lakes").appendChild(newGroup);
newGroup.id = group;
document.getElementById('lakeGroup').options.add(new Option(group, group, false, true));
document.getElementById("lakeGroup").options.add(new Option(group, group, false, true));
document.getElementById(group).appendChild(elSelected.node());
toggleNewGroupInput();
document.getElementById('lakeGroupName').value = '';
document.getElementById("lakeGroupName").value = "";
}
function removeLakeGroup() {
const group = elSelected.node().parentNode.id;
if (['freshwater', 'salt', 'sinkhole', 'frozen', 'lava', 'dry'].includes(group)) {
tip('This is one of the default groups, it cannot be removed', false, 'error');
if (["freshwater", "salt", "sinkhole", "frozen", "lava", "dry"].includes(group)) {
tip("This is one of the default groups, it cannot be removed", false, "error");
return;
}
@ -236,21 +236,20 @@ function editLake() {
}
}
});
confirmationDialog({title: 'Remove lake group', message, confirm: 'Remove', onConfirm});
}
function editGroupStyle() {
const g = elSelected.node().parentNode.id;
editStyle('lakes', g);
editStyle("lakes", g);
}
function editLakeLegend() {
const id = elSelected.attr('id');
editNotes(id, getLake().name + ' ' + lakeGroup.value + ' lake');
const id = elSelected.attr("id");
editNotes(id, getLake().name + " " + lakeGroup.value + " lake");
}
function closeLakesEditor() {
debug.select('#vertices').remove();
debug.select("#vertices").remove();
unselect();
}
}