mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
markers rework - editor functions
This commit is contained in:
parent
def32b7f74
commit
95f9d990d9
8 changed files with 633 additions and 214 deletions
10
index.css
10
index.css
|
|
@ -238,8 +238,7 @@ i.icon-lock {
|
||||||
}
|
}
|
||||||
|
|
||||||
#routeEditor > *,
|
#routeEditor > *,
|
||||||
#labelEditor div,
|
#labelEditor div {
|
||||||
#markerEditor div {
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1525,7 +1524,8 @@ div.states > .coaIcon > use {
|
||||||
|
|
||||||
#stateNameEditor div.label,
|
#stateNameEditor div.label,
|
||||||
#provinceNameEditor div.label,
|
#provinceNameEditor div.label,
|
||||||
#regimentBody div.label {
|
#regimentBody div.label,
|
||||||
|
#markerEditor div.label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 5.5em;
|
width: 5.5em;
|
||||||
}
|
}
|
||||||
|
|
@ -1974,10 +1974,6 @@ div.textual span,
|
||||||
dominant-baseline: central;
|
dominant-baseline: central;
|
||||||
}
|
}
|
||||||
|
|
||||||
#markerEditor > button {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlighted {
|
.highlighted {
|
||||||
outline-width: 2px;
|
outline-width: 2px;
|
||||||
outline-style: dashed;
|
outline-style: dashed;
|
||||||
|
|
|
||||||
77
index.html
77
index.html
|
|
@ -2036,40 +2036,67 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="markerEditor" class="dialog" style="display: none">
|
<div id="markerEditor" class="dialog" style="display: none">
|
||||||
|
<div id="markerBody" style="padding-bottom: .3em">
|
||||||
<button id="markerGroup" data-tip="Change marker type" class="icon-tags"></button>
|
<div data-tip="Marker type. Style changes will apply to all markers of the same type. Leave blank if the marker is unique">
|
||||||
<div id="markerGroupSection" style="display: none">
|
<div class="label">Type:</div>
|
||||||
<select id="markerSelectGroup" data-tip="Select type for the selected marker" style="width: 10em"></select>
|
<input id="markerType" />
|
||||||
<input id="markerInputGroup" data-tip="Create new type for selected marker" placeholder="type new name" style="display: none; width: 10em"/>
|
|
||||||
<i id="markerAddGroup" data-tip="Create new markers type" class="icon-plus pointer"></i>
|
|
||||||
<i id="markerRemoveGroup" data-tip="Remove all markers of that type" class="icon-trash pointer"></i>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="markerIcon" data-tip="Change marker icon and edit positioning" class="icon-star"></button>
|
<div data-tip="Marker icon. Paste any Unicode symbol or select from the predefined list">
|
||||||
<div id="markerIconSection" style="display: none">
|
<div class="label">Icon:</div>
|
||||||
<i data-tip="Change marker icon size" class="icon-resize-full"></i>
|
<input id="markerIcon" style="width:5em" />
|
||||||
<input id="markerIconSize" data-tip="Change marker icon size" type="range" min=5 max=30 step=.5 value=22 style="width:12em"><br>
|
<button id="markerIconSelect" style="padding: 0; width: 4.5em">select</button>
|
||||||
<i data-tip="Marker Icon" class="icon-info"></i>
|
|
||||||
<button id="markerIconSelect" data-tip="Click to select icon"></button>
|
|
||||||
<i data-tip="Change marker horizontal shift" class="icon-resize-horizontal"></i>
|
|
||||||
<input id="markerIconShiftX" data-tip="Change icon horizontal shift" type="number" value=50>
|
|
||||||
<i data-tip="Change marker vertical shift" class="icon-resize-vertical"></i>
|
|
||||||
<input id="markerIconShiftY" data-tip="Change vertical shift" type="number" min=0 max=100 value=50>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="markerStyle" data-tip="Change marker size and colors" class="icon-brush"></button>
|
<div data-tip="Marker icon size in pixels">
|
||||||
<div id="markerStyleSection" style="display: none">
|
<div class="label">Icon size:</div>
|
||||||
<i data-tip="Change marker base (pin) style" class="icon-map-pin"></i>
|
<input id="markerIconSize" type="number" min="2" max="20" step="0.5" />
|
||||||
<input id="markerSize" data-tip="Change marker size" type="range" min=.01 max=10 step=.1 value=1 style="width:12em">
|
|
||||||
<input id="markerBaseStroke" data-tip="Change pin stroke color" type="color" value="#ffffff">
|
|
||||||
<input id="markerBaseFill" data-tip="Change pin fill color" type="color" alue="#000000">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="markerToggleBubble" data-tip="Toggle pin (bubble) display" class="icon-info-circled"></button>
|
<div data-tip="Marker icon shift (by X and by Y axis), percent. Set to 50 to position icon in center">
|
||||||
<button id="markerLegendButton" data-tip="Edit place legend (free text notes)" class="icon-edit"></button>
|
<div class="label">Icon shift:</div>
|
||||||
|
<input id="markerIconShiftX" type="number" min="0" max="100" step="1" style="width:5em" />
|
||||||
|
<input id="markerIconShiftY" type="number" min="0" max="100" step="1" style="width:5em" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-tip="Size of the marker">
|
||||||
|
<div class="label">Marker size:</div>
|
||||||
|
<input id="markerSize" type="number" min="2" max="500" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-tip="Marker pin shape">
|
||||||
|
<div class="label">Pin shape:</div>
|
||||||
|
<select id="markerPin" >
|
||||||
|
<option value="bubble">Bubble</option>
|
||||||
|
<option value="pin">Pin</option>
|
||||||
|
<option value="square">Square</option>
|
||||||
|
<option value="squarish">Squarish</option>
|
||||||
|
<option value="diamond">Diamond</option>
|
||||||
|
<option value="hex">Hex</option>
|
||||||
|
<option value="hexy">Hexy</option>
|
||||||
|
<option value="shieldy">Shieldy</option>
|
||||||
|
<option value="shield">Shield</option>
|
||||||
|
<option value="pentagon">Pentagon</option>
|
||||||
|
<option value="heptagon">Heptagon</option>
|
||||||
|
<option value="circle">Circle</option>
|
||||||
|
<option value="no">No</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-tip="Pin fill and stroke colors">
|
||||||
|
<div class="label">Pin colors:</div>
|
||||||
|
<input id="markerFill" type="color" style="width:5em" />
|
||||||
|
<input id="markerStroke" type="color" style="width:5em" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="markerBottom">
|
||||||
|
<button id="markerNotes" data-tip="Edit place legend (notes)" class="icon-edit"></button>
|
||||||
|
<button id="markerLock" class="icon-lock-open"></button>
|
||||||
<button id="markerAdd" data-tip="Add additional marker of that type" class="icon-plus"></button>
|
<button id="markerAdd" data-tip="Add additional marker of that type" class="icon-plus"></button>
|
||||||
<button id="markerRemove" data-tip="Remove the marker. Shortcut: Delete" class="icon-trash fastDelete"></button>
|
<button id="markerRemove" data-tip="Remove the marker. Shortcut: Delete" class="icon-trash fastDelete"></button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="regimentEditor" class="dialog" style="display: none">
|
<div id="regimentEditor" class="dialog" style="display: none">
|
||||||
|
|
||||||
|
|
|
||||||
49
main.js
49
main.js
|
|
@ -338,11 +338,39 @@ function findBurgForMFCG(params) {
|
||||||
|
|
||||||
// apply default biomes data
|
// apply default biomes data
|
||||||
function applyDefaultBiomesSystem() {
|
function applyDefaultBiomesSystem() {
|
||||||
const name = ["Marine", "Hot desert", "Cold desert", "Savanna", "Grassland", "Tropical seasonal forest", "Temperate deciduous forest", "Tropical rainforest", "Temperate rainforest", "Taiga", "Tundra", "Glacier", "Wetland"];
|
const name = [
|
||||||
|
"Marine",
|
||||||
|
"Hot desert",
|
||||||
|
"Cold desert",
|
||||||
|
"Savanna",
|
||||||
|
"Grassland",
|
||||||
|
"Tropical seasonal forest",
|
||||||
|
"Temperate deciduous forest",
|
||||||
|
"Tropical rainforest",
|
||||||
|
"Temperate rainforest",
|
||||||
|
"Taiga",
|
||||||
|
"Tundra",
|
||||||
|
"Glacier",
|
||||||
|
"Wetland"
|
||||||
|
];
|
||||||
const color = ["#466eab", "#fbe79f", "#b5b887", "#d2d082", "#c8d68f", "#b6d95d", "#29bc56", "#7dcb35", "#409c43", "#4b6b32", "#96784b", "#d5e7eb", "#0b9131"];
|
const color = ["#466eab", "#fbe79f", "#b5b887", "#d2d082", "#c8d68f", "#b6d95d", "#29bc56", "#7dcb35", "#409c43", "#4b6b32", "#96784b", "#d5e7eb", "#0b9131"];
|
||||||
const habitability = [0, 4, 10, 22, 30, 50, 100, 80, 90, 12, 4, 0, 12];
|
const habitability = [0, 4, 10, 22, 30, 50, 100, 80, 90, 12, 4, 0, 12];
|
||||||
const iconsDensity = [0, 3, 2, 120, 120, 120, 120, 150, 150, 100, 5, 0, 150];
|
const iconsDensity = [0, 3, 2, 120, 120, 120, 120, 150, 150, 100, 5, 0, 150];
|
||||||
const icons = [{}, {dune: 3, cactus: 6, deadTree: 1}, {dune: 9, deadTree: 1}, {acacia: 1, grass: 9}, {grass: 1}, {acacia: 8, palm: 1}, {deciduous: 1}, {acacia: 5, palm: 3, deciduous: 1, swamp: 1}, {deciduous: 6, swamp: 1}, {conifer: 1}, {grass: 1}, {}, {swamp: 1}];
|
const icons = [
|
||||||
|
{},
|
||||||
|
{dune: 3, cactus: 6, deadTree: 1},
|
||||||
|
{dune: 9, deadTree: 1},
|
||||||
|
{acacia: 1, grass: 9},
|
||||||
|
{grass: 1},
|
||||||
|
{acacia: 8, palm: 1},
|
||||||
|
{deciduous: 1},
|
||||||
|
{acacia: 5, palm: 3, deciduous: 1, swamp: 1},
|
||||||
|
{deciduous: 6, swamp: 1},
|
||||||
|
{conifer: 1},
|
||||||
|
{grass: 1},
|
||||||
|
{},
|
||||||
|
{swamp: 1}
|
||||||
|
];
|
||||||
const cost = [10, 200, 150, 60, 50, 70, 70, 80, 90, 200, 1000, 5000, 150]; // biome movement cost
|
const cost = [10, 200, 150, 60, 50, 70, 70, 80, 90, 200, 1000, 5000, 150]; // biome movement cost
|
||||||
const biomesMartix = [
|
const biomesMartix = [
|
||||||
// hot ↔ cold [>19°C; <-4°C]; dry ↕ wet
|
// hot ↔ cold [>19°C; <-4°C]; dry ↕ wet
|
||||||
|
|
@ -494,9 +522,7 @@ function invokeActiveZooming() {
|
||||||
+markers.attr("rescale") &&
|
+markers.attr("rescale") &&
|
||||||
pack.markers?.forEach(marker => {
|
pack.markers?.forEach(marker => {
|
||||||
const {i, x, y, size = 30, hidden} = marker;
|
const {i, x, y, size = 30, hidden} = marker;
|
||||||
if (hidden) return;
|
const el = !hidden && document.getElementById(`marker${i}`);
|
||||||
|
|
||||||
const el = document.getElementById(`marker${i}`);
|
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
const zoomedSize = Math.max(rn(size / 5 + 24 / scale, 2), 1);
|
const zoomedSize = Math.max(rn(size / 5 + 24 / scale, 2), 1);
|
||||||
|
|
@ -1483,7 +1509,18 @@ function addZones(number = 1) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const invasion = rw({Invasion: 4, Occupation: 3, Raid: 2, Conquest: 2, Subjugation: 1, Foray: 1, Skirmishes: 1, Incursion: 2, Pillaging: 1, Intervention: 1});
|
const invasion = rw({
|
||||||
|
Invasion: 4,
|
||||||
|
Occupation: 3,
|
||||||
|
Raid: 2,
|
||||||
|
Conquest: 2,
|
||||||
|
Subjugation: 1,
|
||||||
|
Foray: 1,
|
||||||
|
Skirmishes: 1,
|
||||||
|
Incursion: 2,
|
||||||
|
Pillaging: 1,
|
||||||
|
Intervention: 1
|
||||||
|
});
|
||||||
const name = getAdjective(invader.name) + " " + invasion;
|
const name = getAdjective(invader.name) + " " + invasion;
|
||||||
data.push({name, type: "Invasion", cells: cellsArray, fill: "url(#hatch1)"});
|
data.push({name, type: "Invasion", cells: cellsArray, fill: "url(#hatch1)"});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ window.Markers = (function () {
|
||||||
TIME && console.time("addMarkers");
|
TIME && console.time("addMarkers");
|
||||||
|
|
||||||
const culturesSet = document.getElementById("culturesSet").value;
|
const culturesSet = document.getElementById("culturesSet").value;
|
||||||
|
// TODO: don't put multiple markers to the same cell
|
||||||
|
|
||||||
addVolcanoes();
|
addVolcanoes();
|
||||||
addHotSprings();
|
addHotSprings();
|
||||||
|
|
@ -120,7 +121,9 @@ window.Markers = (function () {
|
||||||
const {cells, burgs} = pack;
|
const {cells, burgs} = pack;
|
||||||
|
|
||||||
const meanFlux = d3.mean(cells.fl.filter(fl => fl));
|
const meanFlux = d3.mean(cells.fl.filter(fl => fl));
|
||||||
let bridges = Array.from(cells.i.filter(i => cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux));
|
let bridges = Array.from(
|
||||||
|
cells.i.filter(i => cells.burg[i] && cells.t[i] !== 1 && burgs[cells.burg[i]].population > 20 && cells.r[i] && cells.fl[i] > meanFlux)
|
||||||
|
);
|
||||||
let quantity = getQuantity(bridges, 1, 5);
|
let quantity = getQuantity(bridges, 1, 5);
|
||||||
if (!quantity) return;
|
if (!quantity) return;
|
||||||
|
|
||||||
|
|
@ -143,13 +146,233 @@ window.Markers = (function () {
|
||||||
let quantity = getQuantity(taverns, 1, 100);
|
let quantity = getQuantity(taverns, 1, 100);
|
||||||
if (!quantity) return;
|
if (!quantity) return;
|
||||||
|
|
||||||
const colors = ["Dark", "Light", "Bright", "Golden", "White", "Black", "Red", "Pink", "Purple", "Blue", "Green", "Yellow", "Amber", "Orange", "Brown", "Grey"];
|
const colors = [
|
||||||
const animals = ["Antelope", "Ape", "Badger", "Bear", "Beaver", "Bison", "Boar", "Buffalo", "Cat", "Crane", "Crocodile", "Crow", "Deer", "Dog", "Eagle", "Elk", "Fox", "Goat", "Goose", "Hare", "Hawk", "Heron", "Horse", "Hyena", "Ibis", "Jackal", "Jaguar", "Lark", "Leopard", "Lion", "Mantis", "Marten", "Moose", "Mule", "Narwhal", "Owl", "Panther", "Rat", "Raven", "Rook", "Scorpion", "Shark", "Sheep", "Snake", "Spider", "Swan", "Tiger", "Turtle", "Wolf", "Wolverine", "Camel", "Falcon", "Hound", "Ox"];
|
"Dark",
|
||||||
const adjectives = ["New", "Good", "High", "Old", "Great", "Big", "Major", "Happy", "Main", "Huge", "Far", "Beautiful", "Fair", "Prime", "Ancient", "Golden", "Proud", "Lucky", "Fat", "Honest", "Giant", "Distant", "Friendly", "Loud", "Hungry", "Magical", "Superior", "Peaceful", "Frozen", "Divine", "Favorable", "Brave", "Sunny", "Flying"];
|
"Light",
|
||||||
const methods = ["Boiled", "Grilled", "Roasted", "Spit-roasted", "Stewed", "Stuffed", "Jugged", "Mashed", "Baked", "Braised", "Poached", "Marinated", "Pickled", "Smoked", "Dried", "Dry-aged", "Corned", "Fried", "Pan-fried", "Deep-fried", "Dressed", "Steamed", "Cured", "Syrupped", "Flame-Broiled"];
|
"Bright",
|
||||||
const courses = ["beef", "pork", "bacon", "chicken", "lamb", "chevon", "hare", "rabbit", "hart", "deer", "antlers", "bear", "buffalo", "badger", "beaver", "turkey", "pheasant", "duck", "goose", "teal", "quail", "pigeon", "seal", "carp", "bass", "pike", "catfish", "sturgeon", "escallop", "pie", "cake", "pottage", "pudding", "onions", "carrot", "potato", "beet", "garlic", "cabbage", "eggplant", "eggs", "broccoli", "zucchini", "pepper", "olives", "pumpkin", "spinach", "peas", "chickpea", "beans", "rice", "pasta", "bread", "apples", "peaches", "pears", "melon", "oranges", "mango", "tomatoes", "cheese", "corn", "rat tails", "pig ears"];
|
"Golden",
|
||||||
|
"White",
|
||||||
|
"Black",
|
||||||
|
"Red",
|
||||||
|
"Pink",
|
||||||
|
"Purple",
|
||||||
|
"Blue",
|
||||||
|
"Green",
|
||||||
|
"Yellow",
|
||||||
|
"Amber",
|
||||||
|
"Orange",
|
||||||
|
"Brown",
|
||||||
|
"Grey"
|
||||||
|
];
|
||||||
|
const animals = [
|
||||||
|
"Antelope",
|
||||||
|
"Ape",
|
||||||
|
"Badger",
|
||||||
|
"Bear",
|
||||||
|
"Beaver",
|
||||||
|
"Bison",
|
||||||
|
"Boar",
|
||||||
|
"Buffalo",
|
||||||
|
"Cat",
|
||||||
|
"Crane",
|
||||||
|
"Crocodile",
|
||||||
|
"Crow",
|
||||||
|
"Deer",
|
||||||
|
"Dog",
|
||||||
|
"Eagle",
|
||||||
|
"Elk",
|
||||||
|
"Fox",
|
||||||
|
"Goat",
|
||||||
|
"Goose",
|
||||||
|
"Hare",
|
||||||
|
"Hawk",
|
||||||
|
"Heron",
|
||||||
|
"Horse",
|
||||||
|
"Hyena",
|
||||||
|
"Ibis",
|
||||||
|
"Jackal",
|
||||||
|
"Jaguar",
|
||||||
|
"Lark",
|
||||||
|
"Leopard",
|
||||||
|
"Lion",
|
||||||
|
"Mantis",
|
||||||
|
"Marten",
|
||||||
|
"Moose",
|
||||||
|
"Mule",
|
||||||
|
"Narwhal",
|
||||||
|
"Owl",
|
||||||
|
"Panther",
|
||||||
|
"Rat",
|
||||||
|
"Raven",
|
||||||
|
"Rook",
|
||||||
|
"Scorpion",
|
||||||
|
"Shark",
|
||||||
|
"Sheep",
|
||||||
|
"Snake",
|
||||||
|
"Spider",
|
||||||
|
"Swan",
|
||||||
|
"Tiger",
|
||||||
|
"Turtle",
|
||||||
|
"Wolf",
|
||||||
|
"Wolverine",
|
||||||
|
"Camel",
|
||||||
|
"Falcon",
|
||||||
|
"Hound",
|
||||||
|
"Ox"
|
||||||
|
];
|
||||||
|
const adjectives = [
|
||||||
|
"New",
|
||||||
|
"Good",
|
||||||
|
"High",
|
||||||
|
"Old",
|
||||||
|
"Great",
|
||||||
|
"Big",
|
||||||
|
"Major",
|
||||||
|
"Happy",
|
||||||
|
"Main",
|
||||||
|
"Huge",
|
||||||
|
"Far",
|
||||||
|
"Beautiful",
|
||||||
|
"Fair",
|
||||||
|
"Prime",
|
||||||
|
"Ancient",
|
||||||
|
"Golden",
|
||||||
|
"Proud",
|
||||||
|
"Lucky",
|
||||||
|
"Fat",
|
||||||
|
"Honest",
|
||||||
|
"Giant",
|
||||||
|
"Distant",
|
||||||
|
"Friendly",
|
||||||
|
"Loud",
|
||||||
|
"Hungry",
|
||||||
|
"Magical",
|
||||||
|
"Superior",
|
||||||
|
"Peaceful",
|
||||||
|
"Frozen",
|
||||||
|
"Divine",
|
||||||
|
"Favorable",
|
||||||
|
"Brave",
|
||||||
|
"Sunny",
|
||||||
|
"Flying"
|
||||||
|
];
|
||||||
|
const methods = [
|
||||||
|
"Boiled",
|
||||||
|
"Grilled",
|
||||||
|
"Roasted",
|
||||||
|
"Spit-roasted",
|
||||||
|
"Stewed",
|
||||||
|
"Stuffed",
|
||||||
|
"Jugged",
|
||||||
|
"Mashed",
|
||||||
|
"Baked",
|
||||||
|
"Braised",
|
||||||
|
"Poached",
|
||||||
|
"Marinated",
|
||||||
|
"Pickled",
|
||||||
|
"Smoked",
|
||||||
|
"Dried",
|
||||||
|
"Dry-aged",
|
||||||
|
"Corned",
|
||||||
|
"Fried",
|
||||||
|
"Pan-fried",
|
||||||
|
"Deep-fried",
|
||||||
|
"Dressed",
|
||||||
|
"Steamed",
|
||||||
|
"Cured",
|
||||||
|
"Syrupped",
|
||||||
|
"Flame-Broiled"
|
||||||
|
];
|
||||||
|
const courses = [
|
||||||
|
"beef",
|
||||||
|
"pork",
|
||||||
|
"bacon",
|
||||||
|
"chicken",
|
||||||
|
"lamb",
|
||||||
|
"chevon",
|
||||||
|
"hare",
|
||||||
|
"rabbit",
|
||||||
|
"hart",
|
||||||
|
"deer",
|
||||||
|
"antlers",
|
||||||
|
"bear",
|
||||||
|
"buffalo",
|
||||||
|
"badger",
|
||||||
|
"beaver",
|
||||||
|
"turkey",
|
||||||
|
"pheasant",
|
||||||
|
"duck",
|
||||||
|
"goose",
|
||||||
|
"teal",
|
||||||
|
"quail",
|
||||||
|
"pigeon",
|
||||||
|
"seal",
|
||||||
|
"carp",
|
||||||
|
"bass",
|
||||||
|
"pike",
|
||||||
|
"catfish",
|
||||||
|
"sturgeon",
|
||||||
|
"escallop",
|
||||||
|
"pie",
|
||||||
|
"cake",
|
||||||
|
"pottage",
|
||||||
|
"pudding",
|
||||||
|
"onions",
|
||||||
|
"carrot",
|
||||||
|
"potato",
|
||||||
|
"beet",
|
||||||
|
"garlic",
|
||||||
|
"cabbage",
|
||||||
|
"eggplant",
|
||||||
|
"eggs",
|
||||||
|
"broccoli",
|
||||||
|
"zucchini",
|
||||||
|
"pepper",
|
||||||
|
"olives",
|
||||||
|
"pumpkin",
|
||||||
|
"spinach",
|
||||||
|
"peas",
|
||||||
|
"chickpea",
|
||||||
|
"beans",
|
||||||
|
"rice",
|
||||||
|
"pasta",
|
||||||
|
"bread",
|
||||||
|
"apples",
|
||||||
|
"peaches",
|
||||||
|
"pears",
|
||||||
|
"melon",
|
||||||
|
"oranges",
|
||||||
|
"mango",
|
||||||
|
"tomatoes",
|
||||||
|
"cheese",
|
||||||
|
"corn",
|
||||||
|
"rat tails",
|
||||||
|
"pig ears"
|
||||||
|
];
|
||||||
const types = ["hot", "cold", "fire", "ice", "smoky", "misty", "shiny", "sweet", "bitter", "salty", "sour", "sparkling", "smelly"];
|
const types = ["hot", "cold", "fire", "ice", "smoky", "misty", "shiny", "sweet", "bitter", "salty", "sour", "sparkling", "smelly"];
|
||||||
const drinks = ["wine", "brandy", "jinn", "whisky", "rom", "beer", "cider", "mead", "liquor", "spirit", "vodka", "tequila", "absinthe", "nectar", "milk", "kvass", "kumis", "tea", "water", "juice", "sap"];
|
const drinks = [
|
||||||
|
"wine",
|
||||||
|
"brandy",
|
||||||
|
"jinn",
|
||||||
|
"whisky",
|
||||||
|
"rom",
|
||||||
|
"beer",
|
||||||
|
"cider",
|
||||||
|
"mead",
|
||||||
|
"liquor",
|
||||||
|
"spirit",
|
||||||
|
"vodka",
|
||||||
|
"tequila",
|
||||||
|
"absinthe",
|
||||||
|
"nectar",
|
||||||
|
"milk",
|
||||||
|
"kvass",
|
||||||
|
"kumis",
|
||||||
|
"tea",
|
||||||
|
"water",
|
||||||
|
"juice",
|
||||||
|
"sap"
|
||||||
|
];
|
||||||
|
|
||||||
while (quantity) {
|
while (quantity) {
|
||||||
const [cell] = extractAnyElement(taverns);
|
const [cell] = extractAnyElement(taverns);
|
||||||
|
|
@ -282,7 +505,14 @@ window.Markers = (function () {
|
||||||
|
|
||||||
const subjects = ["Locals", "Old folks", "Old books", "Tipplers"];
|
const subjects = ["Locals", "Old folks", "Old books", "Tipplers"];
|
||||||
const species = ["Ogre", "Troll", "Cyclops", "Giant", "Monster", "Beast", "Dragon", "Undead", "Ghoul", "Vampire"];
|
const species = ["Ogre", "Troll", "Cyclops", "Giant", "Monster", "Beast", "Dragon", "Undead", "Ghoul", "Vampire"];
|
||||||
const modusOperandi = ["steals their cattle", "doesn't mind eating children", "doesn't mind of human flesh", "keeps the region at bay", "eats their kids", "abducts young women"];
|
const modusOperandi = [
|
||||||
|
"steals their cattle",
|
||||||
|
"doesn't mind eating children",
|
||||||
|
"doesn't mind of human flesh",
|
||||||
|
"keeps the region at bay",
|
||||||
|
"eats their kids",
|
||||||
|
"abducts young women"
|
||||||
|
];
|
||||||
|
|
||||||
while (quantity) {
|
while (quantity) {
|
||||||
const [cell] = extractAnyElement(hills);
|
const [cell] = extractAnyElement(hills);
|
||||||
|
|
@ -376,7 +606,38 @@ window.Markers = (function () {
|
||||||
let quantity = getQuantity(roads, 50, 100);
|
let quantity = getQuantity(roads, 50, 100);
|
||||||
if (!quantity) return;
|
if (!quantity) return;
|
||||||
|
|
||||||
const animals = ["Apes", "Badgers", "Bears", "Beavers", "Bisons", "Boars", "Cats", "Crows", "Dogs", "Foxes", "Hares", "Hawks", "Hyenas", "Jackals", "Jaguars", "Leopards", "Lions", "Owls", "Panthers", "Rats", "Ravens", "Rooks", "Scorpions", "Sharks", "Snakes", "Spiders", "Tigers", "Wolfs", "Wolverines", "Falcons"];
|
const animals = [
|
||||||
|
"Apes",
|
||||||
|
"Badgers",
|
||||||
|
"Bears",
|
||||||
|
"Beavers",
|
||||||
|
"Bisons",
|
||||||
|
"Boars",
|
||||||
|
"Cats",
|
||||||
|
"Crows",
|
||||||
|
"Dogs",
|
||||||
|
"Foxes",
|
||||||
|
"Hares",
|
||||||
|
"Hawks",
|
||||||
|
"Hyenas",
|
||||||
|
"Jackals",
|
||||||
|
"Jaguars",
|
||||||
|
"Leopards",
|
||||||
|
"Lions",
|
||||||
|
"Owls",
|
||||||
|
"Panthers",
|
||||||
|
"Rats",
|
||||||
|
"Ravens",
|
||||||
|
"Rooks",
|
||||||
|
"Scorpions",
|
||||||
|
"Sharks",
|
||||||
|
"Snakes",
|
||||||
|
"Spiders",
|
||||||
|
"Tigers",
|
||||||
|
"Wolfs",
|
||||||
|
"Wolverines",
|
||||||
|
"Falcons"
|
||||||
|
];
|
||||||
const types = {brigands: 4, bandits: 3, robbers: 1, highwaymen: 1};
|
const types = {brigands: 4, bandits: 3, robbers: 1, highwaymen: 1};
|
||||||
|
|
||||||
while (quantity) {
|
while (quantity) {
|
||||||
|
|
@ -385,7 +646,18 @@ window.Markers = (function () {
|
||||||
const culture = cells.culture[cell];
|
const culture = cells.culture[cell];
|
||||||
const biome = cells.biome[cell];
|
const biome = cells.biome[cell];
|
||||||
const height = cells.p[cell];
|
const height = cells.p[cell];
|
||||||
const locality = height >= 70 ? "highlander" : [1, 2].includes(biome) ? "desert" : [3, 4].includes(biome) ? "mounted" : [5, 6, 7, 8, 9].includes(biome) ? "forest" : biome === 12 ? "swamp" : "angry";
|
const locality =
|
||||||
|
height >= 70
|
||||||
|
? "highlander"
|
||||||
|
: [1, 2].includes(biome)
|
||||||
|
? "desert"
|
||||||
|
: [3, 4].includes(biome)
|
||||||
|
? "mounted"
|
||||||
|
: [5, 6, 7, 8, 9].includes(biome)
|
||||||
|
? "forest"
|
||||||
|
: biome === 12
|
||||||
|
? "swamp"
|
||||||
|
: "angry";
|
||||||
const name = `${Names.getCulture(culture)} ${ra(animals)}`;
|
const name = `${Names.getCulture(culture)} ${ra(animals)}`;
|
||||||
const legend = `A gang of ${locality} ${rw(types)}`;
|
const legend = `A gang of ${locality} ${rw(types)}`;
|
||||||
notes.push({id, name, legend});
|
notes.push({id, name, legend});
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ function clicked() {
|
||||||
else if (grand.id === "burgIcons") editBurg();
|
else if (grand.id === "burgIcons") editBurg();
|
||||||
else if (parent.id === "ice") editIce();
|
else if (parent.id === "ice") editIce();
|
||||||
else if (parent.id === "terrain") editReliefIcon();
|
else if (parent.id === "terrain") editReliefIcon();
|
||||||
else if (grand.id === "markers") editMarker();
|
else if (grand.id === "markers" || great.id === "markers") editMarker();
|
||||||
else if (grand.id === "coastline") editCoastline();
|
else if (grand.id === "coastline") editCoastline();
|
||||||
else if (great.id === "armies") editRegiment();
|
else if (great.id === "armies") editRegiment();
|
||||||
else if (pack.cells.t[i] === 1) {
|
else if (pack.cells.t[i] === 1) {
|
||||||
|
|
@ -332,7 +332,15 @@ function drawLegend(name, data) {
|
||||||
const width = bbox.width + colOffset * 2;
|
const width = bbox.width + colOffset * 2;
|
||||||
const height = bbox.height + colOffset / 2 + vOffset;
|
const height = bbox.height + colOffset / 2 + vOffset;
|
||||||
|
|
||||||
legend.insert("rect", ":first-child").attr("id", "legendBox").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", backClr).attr("fill-opacity", opacity);
|
legend
|
||||||
|
.insert("rect", ":first-child")
|
||||||
|
.attr("id", "legendBox")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", 0)
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height)
|
||||||
|
.attr("fill", backClr)
|
||||||
|
.attr("fill-opacity", opacity);
|
||||||
|
|
||||||
fitLegendBox();
|
fitLegendBox();
|
||||||
}
|
}
|
||||||
|
|
@ -385,7 +393,15 @@ function createPicker() {
|
||||||
const closePicker = () => contaiter.style("display", "none");
|
const closePicker = () => contaiter.style("display", "none");
|
||||||
|
|
||||||
const contaiter = d3.select("body").append("svg").attr("id", "pickerContainer").attr("width", "100%").attr("height", "100%");
|
const contaiter = d3.select("body").append("svg").attr("id", "pickerContainer").attr("width", "100%").attr("height", "100%");
|
||||||
contaiter.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%").attr("opacity", 0.2).on("mousemove", cl).on("click", closePicker);
|
contaiter
|
||||||
|
.append("rect")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", 0)
|
||||||
|
.attr("width", "100%")
|
||||||
|
.attr("height", "100%")
|
||||||
|
.attr("opacity", 0.2)
|
||||||
|
.on("mousemove", cl)
|
||||||
|
.on("click", closePicker);
|
||||||
const picker = contaiter
|
const picker = contaiter
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("id", "picker")
|
.attr("id", "picker")
|
||||||
|
|
@ -484,9 +500,25 @@ function createPicker() {
|
||||||
const width = bbox.width + 8;
|
const width = bbox.width + 8;
|
||||||
const height = bbox.height + 9;
|
const height = bbox.height + 9;
|
||||||
|
|
||||||
picker.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height).attr("fill", "#ffffff").attr("stroke", "#5d4651").on("mousemove", pos);
|
picker
|
||||||
|
.insert("rect", ":first-child")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", 0)
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height)
|
||||||
|
.attr("fill", "#ffffff")
|
||||||
|
.attr("stroke", "#5d4651")
|
||||||
|
.on("mousemove", pos);
|
||||||
picker.insert("text", ":first-child").attr("x", 291).attr("y", -10).attr("id", "pickerCloseText").text("✕");
|
picker.insert("text", ":first-child").attr("x", 291).attr("y", -10).attr("id", "pickerCloseText").text("✕");
|
||||||
picker.insert("rect", ":first-child").attr("x", 288).attr("y", -21).attr("id", "pickerCloseRect").attr("width", 14).attr("height", 14).on("mousemove", cl).on("click", closePicker);
|
picker
|
||||||
|
.insert("rect", ":first-child")
|
||||||
|
.attr("x", 288)
|
||||||
|
.attr("y", -21)
|
||||||
|
.attr("id", "pickerCloseRect")
|
||||||
|
.attr("width", 14)
|
||||||
|
.attr("height", 14)
|
||||||
|
.on("mousemove", cl)
|
||||||
|
.on("click", closePicker);
|
||||||
picker.insert("text", ":first-child").attr("x", 12).attr("y", -10).attr("id", "pickerLabel").text("Color Picker").on("mousemove", pos);
|
picker.insert("text", ":first-child").attr("x", 12).attr("y", -10).attr("id", "pickerLabel").text("Color Picker").on("mousemove", pos);
|
||||||
picker.insert("rect", ":first-child").attr("x", 0).attr("y", -30).attr("width", width).attr("height", 30).attr("id", "pickerHeader").on("mousemove", pos);
|
picker.insert("rect", ":first-child").attr("x", 0).attr("y", -30).attr("width", width).attr("height", 30).attr("id", "pickerHeader").on("mousemove", pos);
|
||||||
picker.attr("transform", `translate(${(svgWidth - width) / 2},${(svgHeight - height) / 2})`);
|
picker.attr("transform", `translate(${(svgWidth - width) / 2},${(svgHeight - height) / 2})`);
|
||||||
|
|
@ -705,7 +737,14 @@ function highlightElement(element) {
|
||||||
|
|
||||||
const highlight = debug.append("rect").attr("x", box.x).attr("y", box.y).attr("width", box.width).attr("height", box.height).attr("transform", transform);
|
const highlight = debug.append("rect").attr("x", box.x).attr("y", box.y).attr("width", box.width).attr("height", box.height).attr("transform", transform);
|
||||||
|
|
||||||
highlight.classed("highlighted", 1).transition(enter).style("outline-offset", "0px").transition(exit).style("outline-color", "transparent").delay(1000).remove();
|
highlight
|
||||||
|
.classed("highlighted", 1)
|
||||||
|
.transition(enter)
|
||||||
|
.style("outline-offset", "0px")
|
||||||
|
.transition(exit)
|
||||||
|
.style("outline-color", "transparent")
|
||||||
|
.delay(1000)
|
||||||
|
.remove();
|
||||||
|
|
||||||
const tr = parseTransform(transform);
|
const tr = parseTransform(transform);
|
||||||
let x = box.x + box.width / 2;
|
let x = box.x + box.width / 2;
|
||||||
|
|
@ -922,6 +961,7 @@ function selectIcon(initial, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.oninput = e => callback(input.value);
|
||||||
table.onclick = e => {
|
table.onclick = e => {
|
||||||
if (e.target.tagName === "TD") {
|
if (e.target.tagName === "TD") {
|
||||||
input.value = e.target.innerHTML;
|
input.value = e.target.innerHTML;
|
||||||
|
|
@ -948,6 +988,31 @@ function selectIcon(initial, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function confirmationDialog(options) {
|
||||||
|
const {
|
||||||
|
title = "Confirm action",
|
||||||
|
message = "Are you sure you want to continue? <br>The action cannot be reverted",
|
||||||
|
cancel = "Cancel",
|
||||||
|
confirm = "Continue",
|
||||||
|
onCancel,
|
||||||
|
onConfirm
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const buttons = {
|
||||||
|
[confirm]: function () {
|
||||||
|
if (onConfirm) onConfirm();
|
||||||
|
$(this).dialog("close");
|
||||||
|
},
|
||||||
|
[cancel]: function () {
|
||||||
|
if (onCancel) onCancel();
|
||||||
|
$(this).dialog("close");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("alertMessage").innerHTML = message;
|
||||||
|
$("#alert").dialog({resizable: false, title, buttons});
|
||||||
|
}
|
||||||
|
|
||||||
// add and register event listeners to clean up on editor closure
|
// add and register event listeners to clean up on editor closure
|
||||||
function listen(element, event, handler) {
|
function listen(element, event, handler) {
|
||||||
element.addEventListener(event, handler);
|
element.addEventListener(event, handler);
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,8 @@ function drawHeightmap() {
|
||||||
for (const i of d3.range(20, 101)) {
|
for (const i of d3.range(20, 101)) {
|
||||||
if (paths[i].length < 10) continue;
|
if (paths[i].length < 10) continue;
|
||||||
const color = getColor(i, scheme);
|
const color = getColor(i, scheme);
|
||||||
if (terracing) terrs.append("path").attr("d", paths[i]).attr("transform", "translate(.7,1.4)").attr("fill", d3.color(color).darker(terracing)).attr("data-height", i);
|
if (terracing)
|
||||||
|
terrs.append("path").attr("d", paths[i]).attr("transform", "translate(.7,1.4)").attr("fill", d3.color(color).darker(terracing)).attr("data-height", i);
|
||||||
terrs.append("path").attr("d", paths[i]).attr("fill", color).attr("data-height", i);
|
terrs.append("path").attr("d", paths[i]).attr("fill", color).attr("data-height", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -798,7 +799,10 @@ function drawReligions() {
|
||||||
if (!vArray[r]) vArray[r] = [];
|
if (!vArray[r]) vArray[r] = [];
|
||||||
vArray[r].push(points);
|
vArray[r].push(points);
|
||||||
body[r] += "M" + points.join("L");
|
body[r] += "M" + points.join("L");
|
||||||
gap[r] += "M" + vertices.p[chain[0][0]] + chain.reduce((r2, v, i, d) => (!i ? r2 : !v[2] ? r2 + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r2 + "M" + vertices.p[v[0]] : r2), "");
|
gap[r] +=
|
||||||
|
"M" +
|
||||||
|
vertices.p[chain[0][0]] +
|
||||||
|
chain.reduce((r2, v, i, d) => (!i ? r2 : !v[2] ? r2 + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r2 + "M" + vertices.p[v[0]] : r2), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
const bodyData = body.map((p, i) => [p.length > 10 ? p : null, i, religions[i].color]).filter(d => d[0]);
|
const bodyData = body.map((p, i) => [p.length > 10 ? p : null, i, religions[i].color]).filter(d => d[0]);
|
||||||
|
|
@ -966,7 +970,12 @@ function drawStates() {
|
||||||
const gapString = gapData.map(d => `<path id="state-gap${d[1]}" d="${d[0]}" fill="none" stroke="${d[2]}"/>`).join("");
|
const gapString = gapData.map(d => `<path id="state-gap${d[1]}" d="${d[0]}" fill="none" stroke="${d[2]}"/>`).join("");
|
||||||
const clipString = bodyData.map(d => `<clipPath id="state-clip${d[1]}"><use href="#state${d[1]}"/></clipPath>`).join("");
|
const clipString = bodyData.map(d => `<clipPath id="state-clip${d[1]}"><use href="#state${d[1]}"/></clipPath>`).join("");
|
||||||
const haloString = haloData
|
const haloString = haloData
|
||||||
.map(d => `<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666"}"/>`)
|
.map(
|
||||||
|
d =>
|
||||||
|
`<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${
|
||||||
|
d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666"
|
||||||
|
}"/>`
|
||||||
|
)
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
statesBody.html(bodyString + gapString);
|
statesBody.html(bodyString + gapString);
|
||||||
|
|
@ -1219,7 +1228,10 @@ function getProvincesVertices() {
|
||||||
if (!vArray[p]) vArray[p] = [];
|
if (!vArray[p]) vArray[p] = [];
|
||||||
vArray[p].push(points);
|
vArray[p].push(points);
|
||||||
body[p] += "M" + points.join("L");
|
body[p] += "M" + points.join("L");
|
||||||
gap[p] += "M" + vertices.p[chain[0][0]] + chain.reduce((r, v, i, d) => (!i ? r : !v[2] ? r + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r + "M" + vertices.p[v[0]] : r), "");
|
gap[p] +=
|
||||||
|
"M" +
|
||||||
|
vertices.p[chain[0][0]] +
|
||||||
|
chain.reduce((r, v, i, d) => (!i ? r : !v[2] ? r + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r + "M" + vertices.p[v[0]] : r), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// find province visual center
|
// find province visual center
|
||||||
|
|
@ -1300,7 +1312,12 @@ function drawGrid() {
|
||||||
const maxWidth = Math.max(+mapWidthInput.value, graphWidth);
|
const maxWidth = Math.max(+mapWidthInput.value, graphWidth);
|
||||||
const maxHeight = Math.max(+mapHeightInput.value, graphHeight);
|
const maxHeight = Math.max(+mapHeightInput.value, graphHeight);
|
||||||
|
|
||||||
d3.select(pattern).attr("stroke", stroke).attr("stroke-width", width).attr("stroke-dasharray", dasharray).attr("stroke-linecap", linecap).attr("patternTransform", tr);
|
d3.select(pattern)
|
||||||
|
.attr("stroke", stroke)
|
||||||
|
.attr("stroke-width", width)
|
||||||
|
.attr("stroke-dasharray", dasharray)
|
||||||
|
.attr("stroke-linecap", linecap)
|
||||||
|
.attr("patternTransform", tr);
|
||||||
gridOverlay
|
gridOverlay
|
||||||
.append("rect")
|
.append("rect")
|
||||||
.attr("width", maxWidth)
|
.attr("width", maxWidth)
|
||||||
|
|
@ -1510,23 +1527,23 @@ function toggleMarkers(event) {
|
||||||
drawMarkers();
|
drawMarkers();
|
||||||
if (event && isCtrlClick(event)) editStyle("markers");
|
if (event && isCtrlClick(event)) editStyle("markers");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("markers");
|
||||||
editStyle("markers");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
markers.selectAll("*").remove();
|
markers.selectAll("*").remove();
|
||||||
turnButtonOff("toggleMarkers");
|
turnButtonOff("toggleMarkers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawMarkers() {
|
function drawMarkers() {
|
||||||
const html = pack.markers.map(drawMarker);
|
const rescale = +markers.attr("rescale");
|
||||||
|
const html = pack.markers.map(marker => drawMarker(marker, rescale));
|
||||||
markers.html(html.join(""));
|
markers.html(html.join(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPin = (shape = "bubble", fill = "#fff", stroke = "#000") => {
|
const getPin = (shape = "bubble", fill = "#fff", stroke = "#000") => {
|
||||||
if (shape === "bubble") return `<path d="M6,19 l9,10 L24,19" fill="${stroke}" stroke="none" /><circle cx="15" cy="15" r="10" fill="${fill}" stroke="${stroke}"/>`;
|
if (shape === "bubble")
|
||||||
if (shape === "pin") return `<path d="m 15,3 c -5.5,0 -9.7,4.09 -9.7,9.3 0,6.8 9.7,17 9.7,17 0,0 9.7,-10.2 9.7,-17 C 24.7,7.09 20.5,3 15,3 Z" fill="${fill}" stroke="${stroke}"/>`;
|
return `<path d="M6,19 l9,10 L24,19" fill="${stroke}" stroke="none" /><circle cx="15" cy="15" r="10" fill="${fill}" stroke="${stroke}"/>`;
|
||||||
|
if (shape === "pin")
|
||||||
|
return `<path d="m 15,3 c -5.5,0 -9.7,4.09 -9.7,9.3 0,6.8 9.7,17 9.7,17 0,0 9.7,-10.2 9.7,-17 C 24.7,7.09 20.5,3 15,3 Z" fill="${fill}" stroke="${stroke}"/>`;
|
||||||
if (shape === "square") return `<path d="m 20,25 -5,4 -5,-4 z" fill="${stroke}"/><path d="M 5,5 H 25 V 25 H 5 Z" fill="${fill}" stroke="${stroke}"/>`;
|
if (shape === "square") return `<path d="m 20,25 -5,4 -5,-4 z" fill="${stroke}"/><path d="M 5,5 H 25 V 25 H 5 Z" fill="${fill}" stroke="${stroke}"/>`;
|
||||||
if (shape === "squarish") return `<path d="m 5,5 h 20 v 20 h -6 l -4,4 -4,-4 H 5 Z" fill="${fill}" stroke="${stroke}" />`;
|
if (shape === "squarish") return `<path d="m 5,5 h 20 v 20 h -6 l -4,4 -4,-4 H 5 Z" fill="${fill}" stroke="${stroke}" />`;
|
||||||
if (shape === "diamond") return `<path d="M 2,15 15,1 28,15 15,29 Z" fill="${fill}" stroke="${stroke}" />`;
|
if (shape === "diamond") return `<path d="M 2,15 15,1 28,15 15,29 Z" fill="${fill}" stroke="${stroke}" />`;
|
||||||
|
|
@ -1540,14 +1557,14 @@ const getPin = (shape = "bubble", fill = "#fff", stroke = "#000") => {
|
||||||
if (shape === "no") return "";
|
if (shape === "no") return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
function drawMarker(marker) {
|
function drawMarker(marker, rescale = 1) {
|
||||||
const {i, icon, x, y, dx = 50, dy = 50, px = 12, size = 30} = marker;
|
const {i, icon, x, y, dx = 50, dy = 50, px = 12, size = 30} = marker;
|
||||||
const id = `marker${i}`;
|
const id = `marker${i}`;
|
||||||
const zoomSize = Math.max(rn(size / 5 + 24 / scale, 2), 1);
|
const zoomSize = rescale ? Math.max(rn(size / 5 + 24 / scale, 2), 1) : 1;
|
||||||
const viewX = rn(x - zoomSize / 2, 1);
|
const viewX = rn(x - zoomSize / 2, 1);
|
||||||
const viewY = rn(y - zoomSize, 1);
|
const viewY = rn(y - zoomSize, 1);
|
||||||
|
|
||||||
return `<svg id="${id}" viewbox="0 0 30 30" width="${zoomSize}" height="${zoomSize}" x="${viewX}" y="${viewY}">${getPin()}<text x="${dx}%" y="${dy}%" font-size="${px}px" >${icon}</text></svg>`;
|
return `<svg id="${id}" viewbox="0 0 30 30" width="${zoomSize}" height="${zoomSize}" x="${viewX}" y="${viewY}"><g>${getPin()}</g><text x="${dx}%" y="${dy}%" font-size="${px}px" >${icon}</text></svg>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLabels(event) {
|
function toggleLabels(event) {
|
||||||
|
|
@ -1717,15 +1734,21 @@ function drawEmblems() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const burgNodes = nodes.filter(node => node.type === "burg");
|
const burgNodes = nodes.filter(node => node.type === "burg");
|
||||||
const burgString = burgNodes.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`).join("");
|
const burgString = burgNodes
|
||||||
|
.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`)
|
||||||
|
.join("");
|
||||||
emblems.select("#burgEmblems").attr("font-size", sizeBurgs).html(burgString);
|
emblems.select("#burgEmblems").attr("font-size", sizeBurgs).html(burgString);
|
||||||
|
|
||||||
const provinceNodes = nodes.filter(node => node.type === "province");
|
const provinceNodes = nodes.filter(node => node.type === "province");
|
||||||
const provinceString = provinceNodes.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`).join("");
|
const provinceString = provinceNodes
|
||||||
|
.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`)
|
||||||
|
.join("");
|
||||||
emblems.select("#provinceEmblems").attr("font-size", sizeProvinces).html(provinceString);
|
emblems.select("#provinceEmblems").attr("font-size", sizeProvinces).html(provinceString);
|
||||||
|
|
||||||
const stateNodes = nodes.filter(node => node.type === "state");
|
const stateNodes = nodes.filter(node => node.type === "state");
|
||||||
const stateString = stateNodes.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`).join("");
|
const stateString = stateNodes
|
||||||
|
.map(d => `<use data-i="${d.i}" x="${rn(d.x - d.shift)}" y="${rn(d.y - d.shift)}" width="${d.size}em" height="${d.size}em"/>`)
|
||||||
|
.join("");
|
||||||
emblems.select("#stateEmblems").attr("font-size", sizeStates).html(stateString);
|
emblems.select("#stateEmblems").attr("font-size", sizeStates).html(stateString);
|
||||||
|
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
|
|
|
||||||
|
|
@ -3,23 +3,28 @@ function editMarker() {
|
||||||
if (customization) return;
|
if (customization) return;
|
||||||
closeDialogs(".stable");
|
closeDialogs(".stable");
|
||||||
|
|
||||||
const element = d3.event.target.parentElement;
|
const element = d3.event.target.closest("svg");
|
||||||
elSelected = d3.select(element).call(d3.drag().on("start", dragMarker)).classed("draggable", true);
|
const marker = pack.markers.find(({i}) => Number(element.id.slice(6)) === i);
|
||||||
const marker = pack.markers.find(({i}) => Number(elSelected.attr("id").slice(6)) === i);
|
|
||||||
if (!marker) return;
|
if (!marker) return;
|
||||||
|
|
||||||
|
elSelected = d3.select(element).raise().call(d3.drag().on("start", dragMarker)).classed("draggable", true);
|
||||||
|
|
||||||
// dom elements
|
// dom elements
|
||||||
const markerSelectGroup = document.getElementById("markerSelectGroup");
|
const markerType = document.getElementById("markerType");
|
||||||
|
const markerIcon = document.getElementById("markerIcon");
|
||||||
|
const markerIconSelect = document.getElementById("markerIconSelect");
|
||||||
const markerIconSize = document.getElementById("markerIconSize");
|
const markerIconSize = document.getElementById("markerIconSize");
|
||||||
const markerIconShiftX = document.getElementById("markerIconShiftX");
|
const markerIconShiftX = document.getElementById("markerIconShiftX");
|
||||||
const markerIconShiftY = document.getElementById("markerIconShiftY");
|
const markerIconShiftY = document.getElementById("markerIconShiftY");
|
||||||
|
|
||||||
const markerSize = document.getElementById("markerSize");
|
const markerSize = document.getElementById("markerSize");
|
||||||
const markerBaseStroke = document.getElementById("markerBaseStroke");
|
const markerPin = document.getElementById("markerPin");
|
||||||
const markerBaseFill = document.getElementById("markerBaseFill");
|
const markerFill = document.getElementById("markerFill");
|
||||||
|
const markerStroke = document.getElementById("markerStroke");
|
||||||
|
|
||||||
const markerToggleBubble = document.getElementById("markerToggleBubble");
|
const markerNotes = document.getElementById("markerNotes");
|
||||||
const markerIconSelect = document.getElementById("markerIconSelect");
|
const addMarker = document.getElementById("addMarker");
|
||||||
|
const markerAdd = document.getElementById("markerAdd");
|
||||||
|
const markerRemove = document.getElementById("markerRemove");
|
||||||
|
|
||||||
updateInputs();
|
updateInputs();
|
||||||
|
|
||||||
|
|
@ -31,22 +36,27 @@ function editMarker() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const listeners = [
|
const listeners = [
|
||||||
listen(markerSelectGroup, "change", changeGroup),
|
listen(markerType, "change", changeMarkerType),
|
||||||
listen(document.getElementById("markerIcon"), "click", toggleIconSection),
|
listen(markerIcon, "input", changeMarkerIcon),
|
||||||
|
listen(markerIconSelect, "click", selectMarkerIcon),
|
||||||
listen(markerIconSize, "input", changeIconSize),
|
listen(markerIconSize, "input", changeIconSize),
|
||||||
listen(markerIconShiftX, "input", changeIconShiftX),
|
listen(markerIconShiftX, "input", changeIconShiftX),
|
||||||
listen(markerIconShiftY, "input", changeIconShiftY),
|
listen(markerIconShiftY, "input", changeIconShiftY),
|
||||||
listen(document.getElementById("markerIconSelect"), "click", selectMarkerIcon),
|
|
||||||
listen(document.getElementById("markerStyle"), "click", toggleStyleSection),
|
|
||||||
listen(markerSize, "input", changeMarkerSize),
|
listen(markerSize, "input", changeMarkerSize),
|
||||||
listen(markerBaseStroke, "input", changePinStroke),
|
listen(markerPin, "change", changeMarkerPin),
|
||||||
listen(markerBaseFill, "input", changePinFill),
|
listen(markerFill, "input", changePinFill),
|
||||||
listen(markerToggleBubble, "click", togglePinVisibility),
|
listen(markerStroke, "input", changePinStroke),
|
||||||
listen(document.getElementById("markerLegendButton"), "click", editMarkerLegend),
|
listen(markerNotes, "click", editMarkerLegend),
|
||||||
listen(document.getElementById("markerAdd"), "click", toggleAddMarker),
|
listen(markerAdd, "click", toggleAddMarker),
|
||||||
listen(document.getElementById("markerRemove"), "click", removeMarker)
|
listen(markerRemove, "click", confirmMarkerDeletion)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function getSameTypeMarkers() {
|
||||||
|
const currentType = marker.type;
|
||||||
|
if (!currentType) return [marker];
|
||||||
|
return pack.markers.filter(({type}) => type === currentType);
|
||||||
|
}
|
||||||
|
|
||||||
function dragMarker() {
|
function dragMarker() {
|
||||||
const dx = +this.getAttribute("x") - d3.event.x;
|
const dx = +this.getAttribute("x") - d3.event.x;
|
||||||
const dy = +this.getAttribute("y") - d3.event.y;
|
const dy = +this.getAttribute("y") - d3.event.y;
|
||||||
|
|
@ -70,173 +80,147 @@ function editMarker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateInputs() {
|
function updateInputs() {
|
||||||
const {icon, type = "", size = 30, dx = 50, dy = 50, px = 12, stroke = "#000", fill = "#fff", pin = "bubble"} = marker;
|
const {icon, type = "", size = 30, dx = 50, dy = 50, px = 12, stroke = "#000000", fill = "#ffffff", pin = "bubble"} = marker;
|
||||||
|
|
||||||
markerSelectGroup.value = type;
|
markerType.value = type;
|
||||||
|
markerIcon.value = icon;
|
||||||
markerIconSize.value = px;
|
markerIconSize.value = px;
|
||||||
markerIconShiftX.value = dx;
|
markerIconShiftX.value = dx;
|
||||||
markerIconShiftY.value = dy;
|
markerIconShiftY.value = dy;
|
||||||
|
|
||||||
markerSize.value = size;
|
markerSize.value = size;
|
||||||
markerBaseStroke.value = stroke;
|
markerPin.value = pin;
|
||||||
markerBaseFill.value = fill;
|
markerFill.value = fill;
|
||||||
|
markerStroke.value = stroke;
|
||||||
markerToggleBubble.className = pin;
|
|
||||||
markerIconSelect.innerHTML = icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleGroupSection() {
|
function changeMarkerType() {
|
||||||
if (markerGroupSection.style.display === "inline-block") {
|
marker.type = this.value;
|
||||||
markerEditor.querySelectorAll("button:not(#markerGroup)").forEach(b => (b.style.display = "inline-block"));
|
|
||||||
markerGroupSection.style.display = "none";
|
|
||||||
} else {
|
|
||||||
markerEditor.querySelectorAll("button:not(#markerGroup)").forEach(b => (b.style.display = "none"));
|
|
||||||
markerGroupSection.style.display = "inline-block";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeGroup() {
|
function changeMarkerIcon() {
|
||||||
elSelected.attr("xlink:href", "#" + this.value);
|
const icon = this.value;
|
||||||
elSelected.attr("data-id", "#" + this.value);
|
getSameTypeMarkers().forEach(marker => {
|
||||||
}
|
marker.icon = icon;
|
||||||
|
redrawIcon(marker);
|
||||||
function toggleIconSection() {
|
});
|
||||||
console.log(marker);
|
|
||||||
if (markerIconSection.style.display === "inline-block") {
|
|
||||||
markerEditor.querySelectorAll("button:not(#markerIcon)").forEach(b => (b.style.display = "inline-block"));
|
|
||||||
markerIconSection.style.display = "none";
|
|
||||||
markerIconSelect.style.display = "none";
|
|
||||||
} else {
|
|
||||||
markerEditor.querySelectorAll("button:not(#markerIcon)").forEach(b => (b.style.display = "none"));
|
|
||||||
markerIconSection.style.display = "inline-block";
|
|
||||||
markerIconSelect.style.display = "inline-block";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectMarkerIcon() {
|
function selectMarkerIcon() {
|
||||||
selectIcon(this.innerHTML, v => {
|
selectIcon(marker.icon, icon => {
|
||||||
this.innerHTML = v;
|
markerIcon.value = icon;
|
||||||
const id = elSelected.attr("data-id");
|
getSameTypeMarkers().forEach(marker => {
|
||||||
d3.select("#defs-markers").select(id).select("text").text(v);
|
marker.icon = icon;
|
||||||
|
redrawIcon(marker);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconSize() {
|
function changeIconSize() {
|
||||||
const id = elSelected.attr("data-id");
|
const px = +this.value;
|
||||||
d3.select("#defs-markers")
|
getSameTypeMarkers().forEach(marker => {
|
||||||
.select(id)
|
marker.px = px;
|
||||||
.select("text")
|
redrawIcon(marker);
|
||||||
.attr("font-size", this.value + "px");
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconShiftX() {
|
function changeIconShiftX() {
|
||||||
const id = elSelected.attr("data-id");
|
const dx = +this.value;
|
||||||
d3.select("#defs-markers")
|
getSameTypeMarkers().forEach(marker => {
|
||||||
.select(id)
|
marker.dx = dx;
|
||||||
.select("text")
|
redrawIcon(marker);
|
||||||
.attr("x", this.value + "%");
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconShiftY() {
|
function changeIconShiftY() {
|
||||||
const id = elSelected.attr("data-id");
|
const dy = +this.value;
|
||||||
d3.select("#defs-markers")
|
getSameTypeMarkers().forEach(marker => {
|
||||||
.select(id)
|
marker.dy = dy;
|
||||||
.select("text")
|
redrawIcon(marker);
|
||||||
.attr("y", this.value + "%");
|
});
|
||||||
}
|
|
||||||
|
|
||||||
function toggleStyleSection() {
|
|
||||||
if (markerStyleSection.style.display === "inline-block") {
|
|
||||||
markerEditor.querySelectorAll("button:not(#markerStyle)").forEach(b => (b.style.display = "inline-block"));
|
|
||||||
markerStyleSection.style.display = "none";
|
|
||||||
} else {
|
|
||||||
markerEditor.querySelectorAll("button:not(#markerStyle)").forEach(b => (b.style.display = "none"));
|
|
||||||
markerStyleSection.style.display = "inline-block";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeMarkerSize() {
|
function changeMarkerSize() {
|
||||||
const id = elSelected.attr("data-id");
|
const size = +this.value;
|
||||||
document.querySelectorAll("use[data-id='" + id + "']").forEach(e => {
|
const rescale = +markers.attr("rescale");
|
||||||
const x = +e.dataset.x,
|
|
||||||
y = +e.dataset.y;
|
|
||||||
const desired = (e.dataset.size = +markerSize.value);
|
|
||||||
const size = Math.max(desired * 5 + 25 / scale, 1);
|
|
||||||
|
|
||||||
e.setAttribute("x", x - size / 2);
|
getSameTypeMarkers().forEach(marker => {
|
||||||
e.setAttribute("y", y - size / 2);
|
marker.size = size;
|
||||||
e.setAttribute("width", size);
|
const {i, x, y, hidden} = marker;
|
||||||
e.setAttribute("height", size);
|
const el = !hidden && document.getElementById(`marker${i}`);
|
||||||
|
if (!el) return;
|
||||||
|
|
||||||
|
const zoomedSize = rescale ? Math.max(rn(size / 5 + 24 / scale, 2), 1) : size;
|
||||||
|
el.setAttribute("width", zoomedSize);
|
||||||
|
el.setAttribute("height", zoomedSize);
|
||||||
|
el.setAttribute("x", rn(x - zoomedSize / 2, 1));
|
||||||
|
el.setAttribute("y", rn(y - zoomedSize, 1));
|
||||||
});
|
});
|
||||||
invokeActiveZooming();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePinStroke() {
|
function changeMarkerPin() {
|
||||||
const id = elSelected.attr("data-id");
|
const pin = this.value;
|
||||||
d3.select(id).select("path").attr("fill", this.value);
|
getSameTypeMarkers().forEach(marker => {
|
||||||
d3.select(id).select("circle").attr("stroke", this.value);
|
marker.pin = pin;
|
||||||
|
redrawPin(marker);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePinFill() {
|
function changePinFill() {
|
||||||
const id = elSelected.attr("data-id");
|
const fill = this.value;
|
||||||
d3.select(id).select("circle").attr("fill", this.value);
|
getSameTypeMarkers().forEach(marker => {
|
||||||
|
marker.fill = fill;
|
||||||
|
redrawPin(marker);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconStrokeWidth() {
|
function changePinStroke() {
|
||||||
const id = elSelected.attr("data-id");
|
const stroke = this.value;
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("stroke-width", this.value);
|
getSameTypeMarkers().forEach(marker => {
|
||||||
|
marker.stroke = stroke;
|
||||||
|
redrawPin(marker);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconStroke() {
|
function redrawIcon({i, hidden, icon, dx = 50, dy = 50, px = 12}) {
|
||||||
const id = elSelected.attr("data-id");
|
const iconElement = !hidden && document.querySelector(`#marker${i} > text`);
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("stroke", this.value);
|
if (iconElement) {
|
||||||
|
iconElement.innerHTML = icon;
|
||||||
|
iconElement.setAttribute("x", dx + "%");
|
||||||
|
iconElement.setAttribute("y", dy + "%");
|
||||||
|
iconElement.setAttribute("font-size", px + "px");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconFill() {
|
function redrawPin({i, hidden, pin = "bubble", fill = "#fff", stroke = "#000"}) {
|
||||||
const id = elSelected.attr("data-id");
|
const pinGroup = !hidden && document.querySelector(`#marker${i} > g`);
|
||||||
d3.select("#defs-markers").select(id).select("text").attr("fill", this.value);
|
if (pinGroup) pinGroup.innerHTML = getPin(pin, fill, stroke);
|
||||||
}
|
|
||||||
|
|
||||||
function togglePinVisibility() {
|
|
||||||
const id = elSelected.attr("data-id");
|
|
||||||
let show = 1;
|
|
||||||
if (this.className === "icon-info-circled") {
|
|
||||||
this.className = "icon-info";
|
|
||||||
show = 0;
|
|
||||||
} else this.className = "icon-info-circled";
|
|
||||||
d3.select(id).select("circle").attr("opacity", show);
|
|
||||||
d3.select(id).select("path").attr("opacity", show);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function editMarkerLegend() {
|
function editMarkerLegend() {
|
||||||
const id = elSelected.attr("id");
|
const id = element.id;
|
||||||
editNotes(id, id);
|
editNotes(id, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAddMarker() {
|
function toggleAddMarker() {
|
||||||
document.getElementById("addMarker").click();
|
addMarker.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeMarker() {
|
function confirmMarkerDeletion() {
|
||||||
alertMessage.innerHTML = "Are you sure you want to remove the marker?";
|
confirmationDialog({
|
||||||
$("#alert").dialog({
|
|
||||||
resizable: false,
|
|
||||||
title: "Remove marker",
|
title: "Remove marker",
|
||||||
buttons: {
|
message: "Are you sure you want to remove this marker? The action cannot be reverted",
|
||||||
Remove: function () {
|
confirm: "Remove",
|
||||||
$(this).dialog("close");
|
onConfirm: deleteMarker
|
||||||
const index = notes.findIndex(n => n.id === elSelected.attr("id"));
|
|
||||||
if (index != -1) notes.splice(index, 1);
|
|
||||||
elSelected.remove();
|
|
||||||
$("#markerEditor").dialog("close");
|
|
||||||
},
|
|
||||||
Cancel: function () {
|
|
||||||
$(this).dialog("close");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteMarker() {
|
||||||
|
notes = notes.filter(note => note.id !== element.id);
|
||||||
|
pack.markers = pack.markers.filter(m => m.i !== marker.i);
|
||||||
|
element.remove();
|
||||||
|
$("#markerEditor").dialog("close");
|
||||||
|
}
|
||||||
|
|
||||||
function closeMarkerEditor() {
|
function closeMarkerEditor() {
|
||||||
listeners.forEach(removeListener => removeListener());
|
listeners.forEach(removeListener => removeListener());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,9 @@ toolsContent.addEventListener("click", function (event) {
|
||||||
},
|
},
|
||||||
open: function () {
|
open: function () {
|
||||||
const pane = $(this).dialog("widget").find(".ui-dialog-buttonpane");
|
const pane = $(this).dialog("widget").find(".ui-dialog-buttonpane");
|
||||||
$('<span><input id="dontAsk" class="checkbox" type="checkbox"><label for="dontAsk" class="checkbox-label dontAsk"><i>do not ask again</i></label><span>').prependTo(pane);
|
$(
|
||||||
|
'<span><input id="dontAsk" class="checkbox" type="checkbox"><label for="dontAsk" class="checkbox-label dontAsk"><i>do not ask again</i></label><span>'
|
||||||
|
).prependTo(pane);
|
||||||
},
|
},
|
||||||
close: function () {
|
close: function () {
|
||||||
const box = $(this).dialog("widget").find(".checkbox")[0];
|
const box = $(this).dialog("widget").find(".checkbox")[0];
|
||||||
|
|
@ -262,7 +264,8 @@ function regenerateBurgs() {
|
||||||
|
|
||||||
const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for capitals placement
|
const score = new Int16Array(cells.s.map(s => s * Math.random())); // cell score for capitals placement
|
||||||
const sorted = cells.i.filter(i => score[i] > 0 && cells.culture[i]).sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes
|
const sorted = cells.i.filter(i => score[i] > 0 && cells.culture[i]).sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes
|
||||||
const burgsCount = manorsInput.value == 1000 ? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8) + states.length : +manorsInput.value + states.length;
|
const burgsCount =
|
||||||
|
manorsInput.value == 1000 ? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8) + states.length : +manorsInput.value + states.length;
|
||||||
const spacing = (graphWidth + graphHeight) / 150 / (burgsCount ** 0.7 / 66); // base min distance between towns
|
const spacing = (graphWidth + graphHeight) / 150 / (burgsCount ** 0.7 / 66); // base min distance between towns
|
||||||
|
|
||||||
//clear locked list since ids will change
|
//clear locked list since ids will change
|
||||||
|
|
@ -414,6 +417,7 @@ function regenerateIce() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateMarkers(event) {
|
function regenerateMarkers(event) {
|
||||||
|
// TODO: rework for new markers system
|
||||||
if (isCtrlClick(event)) prompt("Please provide markers number multiplier", {default: 1, step: 0.01, min: 0, max: 100}, v => addNumberOfMarkers(v));
|
if (isCtrlClick(event)) prompt("Please provide markers number multiplier", {default: 1, step: 0.01, min: 0, max: 100}, v => addNumberOfMarkers(v));
|
||||||
else addNumberOfMarkers(gauss(1, 0.5, 0.3, 5, 2));
|
else addNumberOfMarkers(gauss(1, 0.5, 0.3, 5, 2));
|
||||||
|
|
||||||
|
|
@ -475,7 +479,18 @@ function addLabelOnClick() {
|
||||||
const id = getNextId("label");
|
const id = getNextId("label");
|
||||||
|
|
||||||
let group = labels.select("#addedLabels");
|
let group = labels.select("#addedLabels");
|
||||||
if (!group.size()) group = labels.append("g").attr("id", "addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null);
|
if (!group.size())
|
||||||
|
group = labels
|
||||||
|
.append("g")
|
||||||
|
.attr("id", "addedLabels")
|
||||||
|
.attr("fill", "#3e3e4b")
|
||||||
|
.attr("opacity", 1)
|
||||||
|
.attr("stroke", "#3a3a3a")
|
||||||
|
.attr("stroke-width", 0)
|
||||||
|
.attr("font-family", "Almendra SC")
|
||||||
|
.attr("font-size", 18)
|
||||||
|
.attr("data-size", 18)
|
||||||
|
.attr("filter", null);
|
||||||
|
|
||||||
const example = group.append("text").attr("x", 0).attr("x", 0).text(name);
|
const example = group.append("text").attr("x", 0).attr("x", 0).text(name);
|
||||||
const width = example.node().getBBox().width;
|
const width = example.node().getBBox().width;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue