mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
Сonfigurable longitude (#1095)
* feat: configurable longitude * chore: update version --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com>
This commit is contained in:
parent
075580da1a
commit
e9ee6967ba
9 changed files with 118 additions and 81 deletions
|
|
@ -2248,10 +2248,6 @@ svg.button {
|
|||
fill: blue;
|
||||
}
|
||||
|
||||
#globeOutline {
|
||||
fill: url(#temperatureGradient);
|
||||
}
|
||||
|
||||
#globeArea {
|
||||
fill: white;
|
||||
fill-opacity: 0.3;
|
||||
|
|
@ -2262,6 +2258,11 @@ svg.button {
|
|||
stroke-width: 0.2;
|
||||
}
|
||||
|
||||
#globePrimeMeridian {
|
||||
stroke: blue;
|
||||
stroke-width: 1.4;
|
||||
}
|
||||
|
||||
#globeEquator {
|
||||
stroke: red;
|
||||
stroke-width: 1.4;
|
||||
|
|
|
|||
56
index.html
56
index.html
|
|
@ -138,7 +138,7 @@
|
|||
}
|
||||
</style>
|
||||
|
||||
<link rel="preload" href="index.css?v=1.97.16" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
||||
<link rel="preload" href="index.css?v=1.98.01" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
||||
<link rel="preload" href="icons.css" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
||||
<link rel="preload" href="libs/jquery-ui.css" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
||||
</head>
|
||||
|
|
@ -2534,15 +2534,15 @@
|
|||
<i data-locked="0" id="lock_mapSize" class="icon-lock-open"></i>
|
||||
<label data-tip="Set map size relative to the world size">
|
||||
<i>Map size:</i>
|
||||
<input id="mapSizeInput" data-stored="mapSize" type="number" min="1" max="100" />%
|
||||
<input id="mapSizeOutput" data-stored="mapSize" type="range" min="1" max="100" />
|
||||
<input id="mapSizeInput" data-stored="mapSize" type="number" min="1" max="100" step="0.1" />%
|
||||
<input id="mapSizeOutput" data-stored="mapSize" type="range" min="1" max="100" step="0.1" />
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<i data-locked="0" id="lock_latitude" class="icon-lock-open"></i>
|
||||
<label data-tip="Set a North-South map shift">
|
||||
<label data-tip="Set a North-South map shift, set to 50 to make map center lie on Equator">
|
||||
<i>Latitudes:</i>
|
||||
<input id="latitudeInput" data-stored="latitude" type="number" min="0" max="100" step="1" />
|
||||
<input id="latitudeInput" data-stored="latitude" type="number" min="0" max="100" step="0.1" />
|
||||
<br /><i>N</i
|
||||
><input
|
||||
id="latitudeOutput"
|
||||
|
|
@ -2550,12 +2550,38 @@
|
|||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
step="0.1"
|
||||
style="width: 10.3em"
|
||||
/><i>S</i>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<i data-locked="0" id="lock_longitude" class="icon-lock-open"></i>
|
||||
<label data-tip="Set a West-East map shift, set to 50 to make map center lie on Prime meridian">
|
||||
<i>Longitudes:</i>
|
||||
<input
|
||||
id="longitudeInput"
|
||||
data-stored="longitude"
|
||||
type="number"
|
||||
min="0"
|
||||
max="100"
|
||||
value="50"
|
||||
step="0.1"
|
||||
/>
|
||||
<br /><i>W</i
|
||||
><input
|
||||
id="longitudeOutput"
|
||||
data-stored="longitude"
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
step="0.1"
|
||||
style="width: 10.3em"
|
||||
/><i>E</i>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label
|
||||
data-tip="Set precipitation - water amount clouds can bring. Defines rivers and biomes generation. Keep around 100% for default generation"
|
||||
|
|
@ -2634,8 +2660,10 @@
|
|||
<text x="-15" y="190">60°</text>
|
||||
<text x="-15" y="204">90°</text>
|
||||
</g>
|
||||
<circle id="globeOutline" cx="100" cy="100" r="100" />
|
||||
<line id="globeEquator" x1="1" x2="199" y1="100" y2="100" />
|
||||
<circle id="globeGradient" cx="100" cy="100" r="100" fill="url(#temperatureGradient)" stroke="none" />
|
||||
<line id="globePrimeMeridian" x1="100" x2="100" y1="0" y2="200" />
|
||||
<line id="globeEquator" x1="1" x2="200" y1="100" y2="100" />
|
||||
<circle id="globeOutline" cx="100" cy="100" r="100" fill="none" />
|
||||
<path id="globeGraticule" />
|
||||
<path id="globeArea" />
|
||||
</svg>
|
||||
|
|
@ -8081,15 +8109,15 @@
|
|||
<script src="modules/ui/measurers.js?v=1.96.00"></script>
|
||||
<script src="modules/ui/stylePresets.js?v=1.96.00"></script>
|
||||
|
||||
<script src="modules/ui/general.js?v=1.96.00"></script>
|
||||
<script src="modules/ui/general.js?v=1.98.01"></script>
|
||||
<script src="modules/ui/options.js?v=1.97.14"></script>
|
||||
<script src="main.js?v=1.98.00"></script>
|
||||
<script src="main.js?v=1.98.01"></script>
|
||||
|
||||
<script defer src="modules/relief-icons.js"></script>
|
||||
<script defer src="modules/ui/style.js?v=1.96.00"></script>
|
||||
<script defer src="modules/ui/editors.js?v=1.97.12"></script>
|
||||
<script defer src="modules/ui/tools.js?v=1.97.12"></script>
|
||||
<script defer src="modules/ui/world-configurator.js?v=1.97.16"></script>
|
||||
<script defer src="modules/ui/world-configurator.js?v=1.98.01"></script>
|
||||
<script defer src="modules/ui/heightmap-editor.js?v=1.96.00"></script>
|
||||
<script defer src="modules/ui/provinces-editor.js?v=1.96.00"></script>
|
||||
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
|
||||
|
|
@ -8124,10 +8152,10 @@
|
|||
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
|
||||
<script defer src="libs/rgbquant.min.js"></script>
|
||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||
<script defer src="modules/io/save.js?v=1.96.00"></script>
|
||||
<script defer src="modules/io/load.js?v=1.98.00"></script>
|
||||
<script defer src="modules/io/save.js?v=1.98.01"></script>
|
||||
<script defer src="modules/io/load.js?v=1.98.01"></script>
|
||||
<script defer src="modules/io/cloud.js?v=1.96.00"></script>
|
||||
<script defer src="modules/io/export.js?v=1.98.00"></script>
|
||||
<script defer src="modules/io/export.js?v=1.98.01"></script>
|
||||
|
||||
<!-- Web Components -->
|
||||
<script defer src="components/fill-box.js"></script>
|
||||
|
|
|
|||
120
main.js
120
main.js
|
|
@ -198,10 +198,10 @@ let options = {
|
|||
};
|
||||
|
||||
let mapCoordinates = {}; // map coordinates on globe
|
||||
let populationRate = +document.getElementById("populationRateInput").value;
|
||||
let distanceScale = +document.getElementById("distanceScaleInput").value;
|
||||
let urbanization = +document.getElementById("urbanizationInput").value;
|
||||
let urbanDensity = +document.getElementById("urbanDensityInput").value;
|
||||
let populationRate = +byId("populationRateInput").value;
|
||||
let distanceScale = +byId("distanceScaleInput").value;
|
||||
let urbanization = +byId("urbanizationInput").value;
|
||||
let urbanDensity = +byId("urbanDensityInput").value;
|
||||
|
||||
applyStoredOptions();
|
||||
|
||||
|
|
@ -442,10 +442,10 @@ function handleZoom(isScaleChanged, isPositionChanged) {
|
|||
|
||||
// zoom image converter overlay
|
||||
if (customization === 1) {
|
||||
const canvas = document.getElementById("canvas");
|
||||
const canvas = byId("canvas");
|
||||
if (!canvas || canvas.style.opacity === "0") return;
|
||||
|
||||
const img = document.getElementById("imageToConvert");
|
||||
const img = byId("imageToConvert");
|
||||
if (!img) return;
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
|
@ -527,7 +527,7 @@ function invokeActiveZooming() {
|
|||
+markers.attr("rescale") &&
|
||||
pack.markers?.forEach(marker => {
|
||||
const {i, x, y, size = 30, hidden} = marker;
|
||||
const el = !hidden && document.getElementById(`marker${i}`);
|
||||
const el = !hidden && byId(`marker${i}`);
|
||||
if (!el) return;
|
||||
|
||||
const zoomedSize = Math.max(rn(size / 5 + 24 / scale, 2), 1);
|
||||
|
|
@ -564,18 +564,18 @@ void (function addDragToUpload() {
|
|||
document.addEventListener("dragover", function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
document.getElementById("mapOverlay").style.display = null;
|
||||
byId("mapOverlay").style.display = null;
|
||||
});
|
||||
|
||||
document.addEventListener("dragleave", function (e) {
|
||||
document.getElementById("mapOverlay").style.display = "none";
|
||||
byId("mapOverlay").style.display = "none";
|
||||
});
|
||||
|
||||
document.addEventListener("drop", function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
const overlay = document.getElementById("mapOverlay");
|
||||
const overlay = byId("mapOverlay");
|
||||
overlay.style.display = "none";
|
||||
if (e.dataTransfer.items == null || e.dataTransfer.items.length !== 1) return; // no files or more than one
|
||||
const file = e.dataTransfer.items[0].getAsFile();
|
||||
|
|
@ -782,7 +782,7 @@ function addLakesInDeepDepressions() {
|
|||
TIME && console.time("addLakesInDeepDepressions");
|
||||
const {cells, features} = grid;
|
||||
const {c, h, b} = cells;
|
||||
const ELEVATION_LIMIT = +document.getElementById("lakeElevationLimitOutput").value;
|
||||
const ELEVATION_LIMIT = +byId("lakeElevationLimitOutput").value;
|
||||
if (ELEVATION_LIMIT === 80) return;
|
||||
|
||||
for (const i of cells.i) {
|
||||
|
|
@ -882,73 +882,77 @@ function openNearSeaLakes() {
|
|||
|
||||
// define map size and position based on template and random factor
|
||||
function defineMapSize() {
|
||||
const [size, latitude] = getSizeAndLatitude();
|
||||
const [size, latitude, longitude] = getSizeAndLatitude();
|
||||
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
|
||||
if (randomize || !locked("mapSize")) mapSizeOutput.value = mapSizeInput.value = rn(size);
|
||||
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = rn(latitude);
|
||||
if (randomize || !locked("mapSize")) mapSizeOutput.value = mapSizeInput.value = size;
|
||||
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = latitude;
|
||||
if (randomize || !locked("longitude")) longitudeOutput.value = longitudeInput.value = longitude;
|
||||
|
||||
function getSizeAndLatitude() {
|
||||
const template = byId("templateInput").value; // heightmap template
|
||||
|
||||
if (template === "africa-centric") return [45, 53];
|
||||
if (template === "arabia") return [20, 35];
|
||||
if (template === "atlantics") return [42, 23];
|
||||
if (template === "britain") return [7, 20];
|
||||
if (template === "caribbean") return [15, 40];
|
||||
if (template === "east-asia") return [11, 28];
|
||||
if (template === "eurasia") return [38, 19];
|
||||
if (template === "europe") return [20, 16];
|
||||
if (template === "europe-accented") return [14, 22];
|
||||
if (template === "europe-and-central-asia") return [25, 10];
|
||||
if (template === "europe-central") return [11, 22];
|
||||
if (template === "europe-north") return [7, 18];
|
||||
if (template === "greenland") return [22, 7];
|
||||
if (template === "hellenica") return [8, 27];
|
||||
if (template === "iceland") return [2, 15];
|
||||
if (template === "indian-ocean") return [45, 55];
|
||||
if (template === "mediterranean-sea") return [10, 29];
|
||||
if (template === "middle-east") return [8, 31];
|
||||
if (template === "north-america") return [37, 17];
|
||||
if (template === "us-centric") return [66, 27];
|
||||
if (template === "us-mainland") return [16, 30];
|
||||
if (template === "world") return [78, 27];
|
||||
if (template === "world-from-pacific") return [75, 32];
|
||||
if (template === "africa-centric") return [45, 53, 38];
|
||||
if (template === "arabia") return [20, 35, 35];
|
||||
if (template === "atlantics") return [42, 23, 65];
|
||||
if (template === "britain") return [7, 20, 51.3];
|
||||
if (template === "caribbean") return [15, 40, 74.8];
|
||||
if (template === "east-asia") return [11, 28, 9.4];
|
||||
if (template === "eurasia") return [38, 19, 27];
|
||||
if (template === "europe") return [20, 16, 44.8];
|
||||
if (template === "europe-accented") return [14, 22, 44.8];
|
||||
if (template === "europe-and-central-asia") return [25, 10, 39.5];
|
||||
if (template === "europe-central") return [11, 22, 46.4];
|
||||
if (template === "europe-north") return [7, 18, 48.9];
|
||||
if (template === "greenland") return [22, 7, 55.8];
|
||||
if (template === "hellenica") return [8, 27, 43.5];
|
||||
if (template === "iceland") return [2, 15, 55.3];
|
||||
if (template === "indian-ocean") return [45, 55, 14];
|
||||
if (template === "mediterranean-sea") return [10, 29, 45.8];
|
||||
if (template === "middle-east") return [8, 31, 34.4];
|
||||
if (template === "north-america") return [37, 17, 87];
|
||||
if (template === "us-centric") return [66, 27, 100];
|
||||
if (template === "us-mainland") return [16, 30, 77.5];
|
||||
if (template === "world") return [78, 27, 40];
|
||||
if (template === "world-from-pacific") return [75, 32, 30]; // longitude doesn't fit
|
||||
|
||||
const part = grid.features.some(f => f.land && f.border); // if land goes over map borders
|
||||
const max = part ? 80 : 100; // max size
|
||||
const lat = () => gauss(P(0.5) ? 40 : 60, 20, 25, 75); // latitude shift
|
||||
|
||||
if (!part) {
|
||||
if (template === "Pangea") return [100, 50];
|
||||
if (template === "Shattered" && P(0.7)) return [100, 50];
|
||||
if (template === "Continents" && P(0.5)) return [100, 50];
|
||||
if (template === "Archipelago" && P(0.35)) return [100, 50];
|
||||
if (template === "High Island" && P(0.25)) return [100, 50];
|
||||
if (template === "Low Island" && P(0.1)) return [100, 50];
|
||||
if (template === "pangea") return [100, 50, 50];
|
||||
if (template === "shattered" && P(0.7)) return [100, 50, 50];
|
||||
if (template === "continents" && P(0.5)) return [100, 50, 50];
|
||||
if (template === "archipelago" && P(0.35)) return [100, 50, 50];
|
||||
if (template === "highIsland" && P(0.25)) return [100, 50, 50];
|
||||
if (template === "lowIsland" && P(0.1)) return [100, 50, 50];
|
||||
}
|
||||
|
||||
if (template === "Pangea") return [gauss(70, 20, 30, max), lat()];
|
||||
if (template === "Volcano") return [gauss(20, 20, 10, max), lat()];
|
||||
if (template === "Mediterranean") return [gauss(25, 30, 15, 80), lat()];
|
||||
if (template === "Peninsula") return [gauss(15, 15, 5, 80), lat()];
|
||||
if (template === "Isthmus") return [gauss(15, 20, 3, 80), lat()];
|
||||
if (template === "Atoll") return [gauss(5, 10, 2, max), lat()];
|
||||
if (template === "pangea") return [gauss(70, 20, 30, max), lat(), 50];
|
||||
if (template === "volcano") return [gauss(20, 20, 10, max), lat(), 50];
|
||||
if (template === "mediterranean") return [gauss(25, 30, 15, 80), lat(), 50];
|
||||
if (template === "peninsula") return [gauss(15, 15, 5, 80), lat(), 50];
|
||||
if (template === "isthmus") return [gauss(15, 20, 3, 80), lat(), 50];
|
||||
if (template === "atoll") return [gauss(3, 2, 1, 5, 1), lat(), 50];
|
||||
|
||||
return [gauss(30, 20, 15, max), lat()]; // Continents, Archipelago, High Island, Low Island
|
||||
return [gauss(30, 20, 15, max), lat(), 50]; // Continents, Archipelago, High Island, Low Island
|
||||
}
|
||||
}
|
||||
|
||||
// calculate map position on globe
|
||||
function calculateMapCoordinates() {
|
||||
const size = +document.getElementById("mapSizeOutput").value;
|
||||
const latShift = +document.getElementById("latitudeOutput").value;
|
||||
const sizeFraction = +byId("mapSizeOutput").value / 100;
|
||||
const latShift = +byId("latitudeOutput").value / 100;
|
||||
const lonShift = +byId("longitudeOutput").value / 100;
|
||||
|
||||
const latT = rn((size / 100) * 180, 1);
|
||||
const latN = rn(90 - ((180 - latT) * latShift) / 100, 1);
|
||||
const latT = rn(sizeFraction * 180, 1);
|
||||
const latN = rn(90 - (180 - latT) * latShift, 1);
|
||||
const latS = rn(latN - latT, 1);
|
||||
|
||||
const lon = rn(Math.min(((graphWidth / graphHeight) * latT) / 2, 180));
|
||||
mapCoordinates = {latT, latN, latS, lonT: lon * 2, lonW: -lon, lonE: lon};
|
||||
const lonT = rn(Math.min((graphWidth / graphHeight) * latT, 360), 1);
|
||||
const lonE = rn(180 - (360 - lonT) * lonShift, 1);
|
||||
const lonW = rn(lonE - lonT, 1);
|
||||
mapCoordinates = {latT, latN, latS, lonT, lonW, lonE};
|
||||
}
|
||||
|
||||
// temperature model, trying to follow real-world data
|
||||
|
|
@ -1750,7 +1754,7 @@ function addZones(number = 1) {
|
|||
}
|
||||
|
||||
function addEruption() {
|
||||
const volcano = document.getElementById("markers").querySelector("use[data-id='#marker_volcano']");
|
||||
const volcano = byId("markers").querySelector("use[data-id='#marker_volcano']");
|
||||
if (!volcano) return;
|
||||
|
||||
const x = +volcano.dataset.x,
|
||||
|
|
@ -1969,7 +1973,7 @@ function undraw() {
|
|||
.getElementById("deftemp")
|
||||
.querySelectorAll("path, clipPath, svg")
|
||||
.forEach(el => el.remove());
|
||||
document.getElementById("coas").innerHTML = ""; // remove auto-generated emblems
|
||||
byId("coas").innerHTML = ""; // remove auto-generated emblems
|
||||
notes = [];
|
||||
rulers = new Rulers();
|
||||
unfog();
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ function getSettings() {
|
|||
populationRate: populationRate,
|
||||
urbanization: urbanization,
|
||||
mapSize: mapSizeOutput.value,
|
||||
latitudeO: latitudeOutput.value,
|
||||
latitude: latitudeOutput.value,
|
||||
longitude: longitudeOutput.value,
|
||||
prec: precOutput.value,
|
||||
options: options,
|
||||
mapName: mapName.value,
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ async function parseLoadedData(data, mapVersion) {
|
|||
if (settings[22]) stylePreset.value = settings[22];
|
||||
if (settings[23]) rescaleLabels.checked = +settings[23];
|
||||
if (settings[24]) urbanDensity = urbanDensityInput.value = urbanDensityOutput.value = +settings[24];
|
||||
if (settings[25]) longitudeInput.value = longitudeOutput.value = minmax(settings[25] || 50, 0, 100);
|
||||
})();
|
||||
|
||||
void (function applyOptionsToUI() {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ function prepareMapData() {
|
|||
+hideLabels.checked,
|
||||
stylePreset.value,
|
||||
+rescaleLabels.checked,
|
||||
urbanDensity
|
||||
urbanDensity,
|
||||
longitudeOutput.value
|
||||
].join("|");
|
||||
const coords = JSON.stringify(mapCoordinates);
|
||||
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ function toDMS(coord, c) {
|
|||
const minutes = Math.floor(minutesNotTruncated);
|
||||
const seconds = Math.floor((minutesNotTruncated - minutes) * 60);
|
||||
const cardinal = c === "lat" ? (coord >= 0 ? "N" : "S") : coord >= 0 ? "E" : "W";
|
||||
return degrees + "° " + minutes + "′ " + seconds + "″ " + cardinal;
|
||||
return degrees + "°" + minutes + "′" + seconds + "″" + cardinal;
|
||||
}
|
||||
|
||||
// get surface elevation
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@ function editWorld() {
|
|||
if (modules.editWorld) return;
|
||||
modules.editWorld = true;
|
||||
|
||||
const graticule = d3.geoGraticule();
|
||||
globe.select("#globeWindArrows").on("click", handleWindChange);
|
||||
globe.select("#globeGraticule").attr("d", round(path(d3.geoGraticule()()))); // globe graticule
|
||||
globe.select("#globeGraticule").attr("d", round(path(graticule()))); // globe graticule
|
||||
updateWindDirections();
|
||||
|
||||
byId("worldControls").on("input", handleControlsChange);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
// version and caching control
|
||||
const version = "1.98.00"; // generator version, update each time
|
||||
const version = "1.98.01"; // generator version, update each time
|
||||
|
||||
{
|
||||
document.title += " v" + version;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue