mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
state labels mode
This commit is contained in:
parent
6de70f5897
commit
4935d506b6
5 changed files with 58 additions and 26 deletions
15
index.html
15
index.html
|
|
@ -1130,6 +1130,21 @@
|
||||||
<output id="religionsOutput" data-stored="religions" value="auto"></output>
|
<output id="religionsOutput" data-stored="religions" value="auto"></output>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr data-tip="Select state labels mode: display short or full names">
|
||||||
|
<td>
|
||||||
|
<i data-locked=0 id="lock_stateLabelsMode" class="icon-lock-open"></i>
|
||||||
|
</td>
|
||||||
|
<td>State labels</td>
|
||||||
|
<td>
|
||||||
|
<select id="stateLabelsModeInput" data-stored="stateLabelsMode">
|
||||||
|
<option value="auto">Auto </option>
|
||||||
|
<option value="short">Short names</option>
|
||||||
|
<option value="full">Full names</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p data-tip="Tool settings that don't affect maps. Changes are getting applied immediately">Generator settings:</p>
|
<p data-tip="Tool settings that don't affect maps. Changes are getting applied immediately">Generator settings:</p>
|
||||||
|
|
|
||||||
3
main.js
3
main.js
|
|
@ -150,7 +150,8 @@ const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomed);
|
||||||
let options = {
|
let options = {
|
||||||
pinNotes: false,
|
pinNotes: false,
|
||||||
showMFCGMap: true,
|
showMFCGMap: true,
|
||||||
winds: [225, 45, 225, 315, 135, 315]
|
winds: [225, 45, 225, 315, 135, 315],
|
||||||
|
stateLabelsMode: "auto"
|
||||||
};
|
};
|
||||||
let mapCoordinates = {}; // map coordinates on globe
|
let mapCoordinates = {}; // map coordinates on globe
|
||||||
let populationRate = +document.getElementById("populationRateInput").value;
|
let populationRate = +document.getElementById("populationRateInput").value;
|
||||||
|
|
|
||||||
|
|
@ -480,6 +480,7 @@ window.BurgsAndStates = (function () {
|
||||||
const {cells, features, states} = pack;
|
const {cells, features, states} = pack;
|
||||||
const paths = []; // text paths
|
const paths = []; // text paths
|
||||||
lineGen.curve(d3.curveBundle.beta(1));
|
lineGen.curve(d3.curveBundle.beta(1));
|
||||||
|
const mode = options.stateLabelsMode || "auto";
|
||||||
|
|
||||||
for (const s of states) {
|
for (const s of states) {
|
||||||
if (!s.i || s.removed || !s.cells || (list && !list.includes(s.i))) continue;
|
if (!s.i || s.removed || !s.cells || (list && !list.includes(s.i))) continue;
|
||||||
|
|
@ -586,7 +587,8 @@ window.BurgsAndStates = (function () {
|
||||||
|
|
||||||
paths.forEach(p => {
|
paths.forEach(p => {
|
||||||
const id = p[0];
|
const id = p[0];
|
||||||
const s = states[p[0]];
|
const state = states[p[0]];
|
||||||
|
const {name, fullName} = state;
|
||||||
|
|
||||||
if (list) {
|
if (list) {
|
||||||
t.select("#textPath_stateLabel" + id).remove();
|
t.select("#textPath_stateLabel" + id).remove();
|
||||||
|
|
@ -600,22 +602,7 @@ window.BurgsAndStates = (function () {
|
||||||
.attr("id", "textPath_stateLabel" + id);
|
.attr("id", "textPath_stateLabel" + id);
|
||||||
const pathLength = p[1].length > 1 ? textPath.node().getTotalLength() / letterLength : 0; // path length in letters
|
const pathLength = p[1].length > 1 ? textPath.node().getTotalLength() / letterLength : 0; // path length in letters
|
||||||
|
|
||||||
let lines = [];
|
const [lines, ratio] = getLines(mode, name, fullName, pathLength);
|
||||||
let ratio = 100;
|
|
||||||
|
|
||||||
if (pathLength < s.name.length) {
|
|
||||||
// only short name will fit
|
|
||||||
lines = splitInTwo(s.name);
|
|
||||||
ratio = minmax(rn((pathLength / lines[0].length) * 60), 50, 150);
|
|
||||||
} else if (pathLength > s.fullName.length * 2.5) {
|
|
||||||
// full name will fit in one line
|
|
||||||
lines = [s.fullName];
|
|
||||||
ratio = minmax(rn((pathLength / lines[0].length) * 70), 70, 170);
|
|
||||||
} else {
|
|
||||||
// try miltilined label
|
|
||||||
lines = splitInTwo(s.fullName);
|
|
||||||
ratio = minmax(rn((pathLength / lines[0].length) * 60), 70, 150);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prolongate path if it's too short
|
// prolongate path if it's too short
|
||||||
if (pathLength && pathLength < lines[0].length) {
|
if (pathLength && pathLength < lines[0].length) {
|
||||||
|
|
@ -647,7 +634,7 @@ window.BurgsAndStates = (function () {
|
||||||
.node();
|
.node();
|
||||||
|
|
||||||
el.insertAdjacentHTML("afterbegin", spans.join(""));
|
el.insertAdjacentHTML("afterbegin", spans.join(""));
|
||||||
if (lines.length < 2) return;
|
if (mode === "full" || lines.length === 1) return;
|
||||||
|
|
||||||
// check whether multilined label is generally inside the state. If no, replace with short name label
|
// check whether multilined label is generally inside the state. If no, replace with short name label
|
||||||
const cs = pack.cells.state;
|
const cs = pack.cells.state;
|
||||||
|
|
@ -658,21 +645,43 @@ window.BurgsAndStates = (function () {
|
||||||
const c4 = () => +cs[findCell(b.x + b.width, b.y + b.height)] === id;
|
const c4 = () => +cs[findCell(b.x + b.width, b.y + b.height)] === id;
|
||||||
const c5 = () => +cs[findCell(b.x + b.width / 2, b.y + b.height)] === id;
|
const c5 = () => +cs[findCell(b.x + b.width / 2, b.y + b.height)] === id;
|
||||||
const c6 = () => +cs[findCell(b.x, b.y + b.height)] === id;
|
const c6 = () => +cs[findCell(b.x, b.y + b.height)] === id;
|
||||||
if (c1() + c2() + c3() + c4() + c5() + c6() > 3) return; // generally inside
|
if (c1() + c2() + c3() + c4() + c5() + c6() > 3) return; // generally inside => exit
|
||||||
|
|
||||||
// use one-line name
|
// move to one-line name
|
||||||
const name = pathLength > s.fullName.length * 1.8 ? s.fullName : s.name;
|
const text = pathLength > fullName.length * 1.8 ? fullName : name;
|
||||||
example.text(name);
|
example.text(text);
|
||||||
const left = example.node().getBBox().width / -2; // x offset
|
const left = example.node().getBBox().width / -2; // x offset
|
||||||
el.innerHTML = `<tspan x="${left}px">${name}</tspan>`;
|
el.innerHTML = `<tspan x="${left}px">${text}</tspan>`;
|
||||||
ratio = minmax(rn((pathLength / name.length) * 60), 40, 130);
|
|
||||||
el.setAttribute("font-size", ratio + "%");
|
const correctedRatio = minmax(rn((pathLength / text.length) * 60), 40, 130);
|
||||||
|
el.setAttribute("font-size", correctedRatio + "%");
|
||||||
});
|
});
|
||||||
|
|
||||||
example.remove();
|
example.remove();
|
||||||
if (!displayed) toggleLabels();
|
if (!displayed) toggleLabels();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function getLines(mode, name, fullName, pathLength) {
|
||||||
|
// short name
|
||||||
|
if (mode === "short" || (mode === "auto" && pathLength < name.length)) {
|
||||||
|
const lines = splitInTwo(name);
|
||||||
|
const ratio = pathLength / lines[0].length;
|
||||||
|
return [lines, minmax(rn(ratio * 60), 50, 150)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// full name: one line
|
||||||
|
if (pathLength > fullName.length * 2.5) {
|
||||||
|
const lines = [fullName];
|
||||||
|
const ratio = pathLength / lines[0].length;
|
||||||
|
return [lines, minmax(rn(ratio * 70), 70, 170)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// full name: two lines
|
||||||
|
const lines = splitInTwo(fullName);
|
||||||
|
const ratio = pathLength / lines[0].length;
|
||||||
|
return [lines, minmax(rn(ratio * 60), 70, 150)];
|
||||||
|
}
|
||||||
|
|
||||||
TIME && console.timeEnd("drawStateLabels");
|
TIME && console.timeEnd("drawStateLabels");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,10 @@ function parseLoadedData(data) {
|
||||||
if (settings[24]) urbanDensity = urbanDensityInput.value = urbanDensityOutput.value = +settings[24];
|
if (settings[24]) urbanDensity = urbanDensityInput.value = urbanDensityOutput.value = +settings[24];
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
void (function applyOptionsToUI() {
|
||||||
|
stateLabelsModeInput.value = options.stateLabelsMode;
|
||||||
|
})();
|
||||||
|
|
||||||
void (function parseConfiguration() {
|
void (function parseConfiguration() {
|
||||||
if (data[2]) mapCoordinates = JSON.parse(data[2]);
|
if (data[2]) mapCoordinates = JSON.parse(data[2]);
|
||||||
if (data[4]) notes = JSON.parse(data[4]);
|
if (data[4]) notes = JSON.parse(data[4]);
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ optionsContent.addEventListener("change", function (event) {
|
||||||
if (id === "shapeRendering") viewbox.attr("shape-rendering", value);
|
if (id === "shapeRendering") viewbox.attr("shape-rendering", value);
|
||||||
else if (id === "yearInput") changeYear();
|
else if (id === "yearInput") changeYear();
|
||||||
else if (id === "eraInput") changeEra();
|
else if (id === "eraInput") changeEra();
|
||||||
|
else if (id === "stateLabelsModeInput") options.stateLabelsMode = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
optionsContent.addEventListener("click", function (event) {
|
optionsContent.addEventListener("click", function (event) {
|
||||||
|
|
@ -533,6 +534,8 @@ function applyStoredOptions() {
|
||||||
|
|
||||||
// set shape rendering
|
// set shape rendering
|
||||||
viewbox.attr("shape-rendering", shapeRendering.value);
|
viewbox.attr("shape-rendering", shapeRendering.value);
|
||||||
|
|
||||||
|
options.stateLabelsMode = stateLabelsModeInput.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// randomize options if randomization is allowed (not locked or options='default')
|
// randomize options if randomization is allowed (not locked or options='default')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue