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>
|
||||
</td>
|
||||
</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>
|
||||
|
||||
<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 = {
|
||||
pinNotes: false,
|
||||
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 populationRate = +document.getElementById("populationRateInput").value;
|
||||
|
|
|
|||
|
|
@ -480,6 +480,7 @@ window.BurgsAndStates = (function () {
|
|||
const {cells, features, states} = pack;
|
||||
const paths = []; // text paths
|
||||
lineGen.curve(d3.curveBundle.beta(1));
|
||||
const mode = options.stateLabelsMode || "auto";
|
||||
|
||||
for (const s of states) {
|
||||
if (!s.i || s.removed || !s.cells || (list && !list.includes(s.i))) continue;
|
||||
|
|
@ -586,7 +587,8 @@ window.BurgsAndStates = (function () {
|
|||
|
||||
paths.forEach(p => {
|
||||
const id = p[0];
|
||||
const s = states[p[0]];
|
||||
const state = states[p[0]];
|
||||
const {name, fullName} = state;
|
||||
|
||||
if (list) {
|
||||
t.select("#textPath_stateLabel" + id).remove();
|
||||
|
|
@ -600,22 +602,7 @@ window.BurgsAndStates = (function () {
|
|||
.attr("id", "textPath_stateLabel" + id);
|
||||
const pathLength = p[1].length > 1 ? textPath.node().getTotalLength() / letterLength : 0; // path length in letters
|
||||
|
||||
let lines = [];
|
||||
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);
|
||||
}
|
||||
const [lines, ratio] = getLines(mode, name, fullName, pathLength);
|
||||
|
||||
// prolongate path if it's too short
|
||||
if (pathLength && pathLength < lines[0].length) {
|
||||
|
|
@ -647,7 +634,7 @@ window.BurgsAndStates = (function () {
|
|||
.node();
|
||||
|
||||
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
|
||||
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 c5 = () => +cs[findCell(b.x + b.width / 2, 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
|
||||
const name = pathLength > s.fullName.length * 1.8 ? s.fullName : s.name;
|
||||
example.text(name);
|
||||
// move to one-line name
|
||||
const text = pathLength > fullName.length * 1.8 ? fullName : name;
|
||||
example.text(text);
|
||||
const left = example.node().getBBox().width / -2; // x offset
|
||||
el.innerHTML = `<tspan x="${left}px">${name}</tspan>`;
|
||||
ratio = minmax(rn((pathLength / name.length) * 60), 40, 130);
|
||||
el.setAttribute("font-size", ratio + "%");
|
||||
el.innerHTML = `<tspan x="${left}px">${text}</tspan>`;
|
||||
|
||||
const correctedRatio = minmax(rn((pathLength / text.length) * 60), 40, 130);
|
||||
el.setAttribute("font-size", correctedRatio + "%");
|
||||
});
|
||||
|
||||
example.remove();
|
||||
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");
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,10 @@ function parseLoadedData(data) {
|
|||
if (settings[24]) urbanDensity = urbanDensityInput.value = urbanDensityOutput.value = +settings[24];
|
||||
})();
|
||||
|
||||
void (function applyOptionsToUI() {
|
||||
stateLabelsModeInput.value = options.stateLabelsMode;
|
||||
})();
|
||||
|
||||
void (function parseConfiguration() {
|
||||
if (data[2]) mapCoordinates = JSON.parse(data[2]);
|
||||
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);
|
||||
else if (id === "yearInput") changeYear();
|
||||
else if (id === "eraInput") changeEra();
|
||||
else if (id === "stateLabelsModeInput") options.stateLabelsMode = value;
|
||||
});
|
||||
|
||||
optionsContent.addEventListener("click", function (event) {
|
||||
|
|
@ -533,6 +534,8 @@ function applyStoredOptions() {
|
|||
|
||||
// set shape rendering
|
||||
viewbox.attr("shape-rendering", shapeRendering.value);
|
||||
|
||||
options.stateLabelsMode = stateLabelsModeInput.value;
|
||||
}
|
||||
|
||||
// randomize options if randomization is allowed (not locked or options='default')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue