-
+
diff --git a/main.js b/main.js
index 7f3a72ce..18c0be34 100644
--- a/main.js
+++ b/main.js
@@ -443,12 +443,12 @@ function invokeActiveZooming() {
else this.classList.remove("hidden");
});
}
-
+
// rescale emblems on zoom
if (emblems.style("display") !== "none") {
emblems.selectAll("g").each(function() {
const size = this.getAttribute("font-size") * scale;
- const hidden = size < 25 || size > 300;
+ const hidden = hideEmblems.checked && (size < 25 || size > 300);
if (hidden) this.classList.add("hidden"); else this.classList.remove("hidden");
if (!hidden && COArenderer && this.children.length && !this.children[0].getAttribute("href")) renderGroupCOAs(this);
});
diff --git a/modules/coa-generator.js b/modules/coa-generator.js
index e0caf2c8..7e852b50 100644
--- a/modules/coa-generator.js
+++ b/modules/coa-generator.js
@@ -195,13 +195,11 @@
let usedPattern = null, usedTinctures = [];
// TODO
- // seafaring
- // old versions auto migration: coa generation for cultures and states etc.
- // emblems layer for old maps
- // define emblems layer style for all styles
+ // seafaring etc
+
// style settings for emblems layer
+ // define emblems layer style for all styles
// test in FF
- // layout preset
const t1 = P(kinship) ? parent.t1 : getTincture("field");
if (t1.includes("-")) usedPattern = t1;
diff --git a/modules/save-and-load.js b/modules/save-and-load.js
index 3e98966d..a039529e 100644
--- a/modules/save-and-load.js
+++ b/modules/save-and-load.js
@@ -331,6 +331,7 @@ function getMapData() {
cloneEl.setAttribute("width", graphWidth);
cloneEl.setAttribute("height", graphHeight);
cloneEl.querySelector("#viewbox").removeAttribute("transform");
+
const svg_xml = (new XMLSerializer()).serializeToString(cloneEl);
const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features});
@@ -600,7 +601,7 @@ function uploadMap(file, callback) {
} else {
load = true;
message = `The map version (${mapVersion}) does not match the Generator version (${version}).
-
Click OK to get map auto-updated. In case of issues please keep using an ${archive} of the Generator`;
+
Click OK to get map
auto-updated. In case of issues please keep using an ${archive} of the Generator`;
}
alertMessage.innerHTML = message;
$("#alert").dialog({title: "Version conflict", width: "38em", buttons: {
@@ -719,6 +720,7 @@ function parseLoadedData(data) {
coastline = viewbox.select("#coastline");
prec = viewbox.select("#prec");
population = viewbox.select("#population");
+ emblems = viewbox.select("#emblems");
labels = viewbox.select("#labels");
icons = viewbox.select("#icons");
burgIcons = icons.select("#burgIcons");
@@ -780,8 +782,8 @@ function parseLoadedData(data) {
}()
const notHidden = selection => selection.style("display") !== "none";
- const hasChildren = selection => selection.node().hasChildNodes();
- const hasChild = (selection, selector) => selection.node().querySelector(selector);
+ const hasChildren = selection => selection.node()?.hasChildNodes();
+ const hasChild = (selection, selector) => selection.node()?.querySelector(selector);
const turnOn = el => document.getElementById(el).classList.remove("buttonoff");
void function restoreLayersState() {
@@ -1068,6 +1070,16 @@ function parseLoadedData(data) {
pack.states.filter(s => s.military).forEach(s => s.military.forEach(r => r.state = s.i));
}
+ if (version < 1.5) {
+ // v 1.5 added emblems
+ emblems = viewbox.append("g").attr("id", "emblems").style("display", "none");
+ emblems.append("g").attr("id", "burgEmblems");
+ emblems.append("g").attr("id", "provinceEmblems");
+ emblems.append("g").attr("id", "stateEmblems");
+ regenerateEmblems();
+ toggleEmblems();
+ }
+
}()
void function checkDataIntegrity() {
@@ -1128,6 +1140,9 @@ function parseLoadedData(data) {
changeMapSize();
+ // remove href from emblems, to trigger rendering on load
+ emblems.selectAll("use").attr("href", null);
+
// set options
yearInput.value = options.year;
eraInput.value = options.era;
@@ -1137,7 +1152,7 @@ function parseLoadedData(data) {
invokeActiveZooming();
WARN && console.warn(`TOTAL: ${rn((performance.now()-uploadMap.timeStart)/1000,2)}s`);
- showStatistics();
+ INFO && showStatistics();
INFO && console.groupEnd("Loaded Map " + seed);
tip("Map is successfully loaded", true, "success", 7000);
}
diff --git a/modules/ui/emblems-editor.js b/modules/ui/emblems-editor.js
index f8f916f2..30262190 100644
--- a/modules/ui/emblems-editor.js
+++ b/modules/ui/emblems-editor.js
@@ -299,6 +299,8 @@ function editEmblem(type, id, el) {
d3.timeout(runDownload, timeout);
function runDownload() {
+ const back = `
Go Back`;
+
const stateSection = `
States
` + validStates.map(state => {
const el = document.getElementById("stateCOA"+state.i);
const svg = getSVG(el, state.coa, 200);
@@ -312,7 +314,7 @@ function editEmblem(type, id, el) {
const svg = getSVG(el, province.coa, 200);
return `
${province.fullName}${svg}`;
}).join("");
- return stateProvinces.length ? `
${state.fullName} provinces
${figures}` : "";
+ return stateProvinces.length ? `
${back}
${state.fullName} provinces
${figures}` : "";
}).join("");
const burgSections = validStates.map(state => {
@@ -324,7 +326,7 @@ function editEmblem(type, id, el) {
const svg = getSVG(el, burg.coa, 200);
return `
${burg.name}${svg}`;
}).join("");
- return provinceBurgs.length ? `
${province.fullName} burgs
${provinceBurgFigures}` : "";
+ return provinceBurgs.length ? `
${back}
${province.fullName} burgs
${provinceBurgFigures}` : "";
}).join("");
const stateBurgOutOfProvinces = stateBurgs.filter(b => !pack.cells.province[b.cell]);
@@ -356,6 +358,7 @@ function editEmblem(type, id, el) {
figcaption { text-align: center; margin: .4em 0; width: 200px; font-family: 'Overlock SC' }
figure > a { color: black; text-decoration: none; }
address { width: 100%; max-width: 1018px; margin: 0 auto; }
+ div > a { float: right; font-family: monospace; margin-top: .8em; }
diff --git a/modules/ui/general.js b/modules/ui/general.js
index 03a1cbfb..90070057 100644
--- a/modules/ui/general.js
+++ b/modules/ui/general.js
@@ -432,6 +432,7 @@ function showInfo() {
// prevent default browser behavior for FMG-used hotkeys
document.addEventListener("keydown", event => {
if (event.altKey && event.keyCode !== 18) event.preventDefault(); // disallow alt key combinations
+ if (event.ctrlKey && event.code === "KeyS") event.preventDefault(); // disallow CTRL + C
if ([112, 113, 117, 120, 9].includes(event.keyCode)) event.preventDefault(); // F1, F2, F6, F9, Tab
});
@@ -460,6 +461,7 @@ document.addEventListener("keyup", event => {
else if (key === 79 && canvas3d) toggle3dOptions(); // "O" to toggle 3d options
else if (ctrl && key === 81) toggleSaveReminder(); // Ctrl + "Q" to toggle save reminder
+ else if (ctrl && key === 83) saveMap(); // Ctrl + "S" to save .map file
else if (undo.offsetParent && ctrl && key === 90) undo.click(); // Ctrl + "Z" to undo
else if (redo.offsetParent && ctrl && key === 89) redo.click(); // Ctrl + "Y" to redo
diff --git a/modules/ui/layers.js b/modules/ui/layers.js
index d7cff0c6..1018e2b6 100644
--- a/modules/ui/layers.js
+++ b/modules/ui/layers.js
@@ -1249,28 +1249,26 @@ function drawEmblems() {
const validStates = states.filter(s => s.i && !s.removed && s.coa);
const validProvinces = provinces.filter(p => p.i && !p.removed && p.coa);
const validBurgs = burgs.filter(b => b.i && !b.removed && b.coa);
-
- const sizeMod = +emblems.attr("size-modifier") || 1;
const getStateEmblemsSize = () => {
- const startSize = (graphHeight + graphWidth) / 40;
+ const startSize = Math.min(Math.max((graphHeight + graphWidth) / 40, 10), 100);
const statesMod = (1 + validStates.length / 100) - (15 - validStates.length) / 200; // states number modifier
- const size = rn(startSize / statesMod * sizeMod); // target size ~50px on 1536x754 map with 15 states
- return Math.min(Math.max(size, 10), 100);
+ const sizeMod = +document.getElementById("styleEmblemsStateSizeInput").value || 1;
+ return rn(startSize / statesMod * sizeMod); // target size ~50px on 1536x754 map with 15 states
};
const getProvinceEmblemsSize = () => {
- const startSize = (graphHeight + graphWidth) / 80;
+ const startSize = Math.min(Math.max((graphHeight + graphWidth) / 80, 5), 75);
const provincesMod = (1 + validProvinces.length / 1000) - (115 - validProvinces.length) / 1000; // states number modifier
- const size = rn(startSize / provincesMod * sizeMod); // target size ~26px on 1536x754 map with 115 provinces
- return Math.min(Math.max(size, 5), 75);
+ const sizeMod = +document.getElementById("styleEmblemsProvinceSizeInput").value || 1;
+ return rn(startSize / provincesMod * sizeMod); // target size ~26px on 1536x754 map with 115 provinces
}
const getBurgEmblemSize = () => {
- const startSize = (graphHeight + graphWidth) / 150;
+ const startSize = Math.min(Math.max((graphHeight + graphWidth) / 150, 5), 50);
const burgsMod = (1 + validBurgs.length / 1000) - (450 - validBurgs.length) / 1000; // states number modifier
- const size = rn(startSize / burgsMod * sizeMod); // target size ~10px on 1536x754 map with 450 burgs
- return Math.min(Math.max(size, 5), 50);
+ const sizeMod = +document.getElementById("styleEmblemsBurgSizeInput").value || 1;
+ return rn(startSize / burgsMod * sizeMod); // target size ~10px on 1536x754 map with 450 burgs
}
const sizeBurgs = getBurgEmblemSize();
diff --git a/modules/ui/style.js b/modules/ui/style.js
index 2b8b5705..259505f8 100644
--- a/modules/ui/style.js
+++ b/modules/ui/style.js
@@ -1,6 +1,11 @@
// UI module to control the style
"use strict";
+// store some style inputs as options
+styleElements.addEventListener("change", function(ev) {
+ if (ev.target.dataset.stored) lock(ev.target.dataset.stored);
+});
+
// select element to be edited
function editStyle(element, group) {
showOptions();
@@ -226,6 +231,10 @@ function selectStyleElement() {
styleArmiesSize.value = styleArmiesSizeOutput.value = el.attr("box-size");
}
+ if (sel === "emblems") {
+ styleEmblems.style.display = "block";
+ }
+
// update group options
styleGroupSelect.options.length = 0; // remove all options
if (sel === "routes" || sel === "labels" || sel === "coastline" || sel === "lakes" || sel === "anchors" || sel === "burgIcons" || sel === "borders") {
@@ -614,6 +623,21 @@ styleArmiesSize.addEventListener("input", function() {
});
});
+styleEmblemsStateSizeInput.addEventListener("input", function() {
+ styleEmblemsStateSizeOutput.value = this.value;
+ drawEmblems();
+});
+
+styleEmblemsProvinceSizeInput.addEventListener("input", function() {
+ styleEmblemsProvinceSizeOutput.value = this.value;
+ drawEmblems();
+});
+
+styleEmblemsBurgSizeInput.addEventListener("input", function() {
+ styleEmblemsBurgSizeOutput.value = this.value;
+ drawEmblems();
+});
+
// request a URL to image to be used as a texture
function textureProvideURL() {
alertMessage.innerHTML = `Provide an image URL to be used as a texture:
@@ -790,7 +814,7 @@ function applyDefaultStyle() {
labels.select("#addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null);
fogging.attr("opacity", .98).attr("fill", "#30426f");
- emblems.attr("opacity", .9).attr("size-modifier", 1).attr("filter", null)
+ emblems.attr("opacity", .9).attr("size-modifier", 1).attr("filter", null);
}
// apply style settings in JSON