mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
Merge branch 'master' of https://github.com/Azgaar/Fantasy-Map-Generator into urquhart-routes
This commit is contained in:
commit
c4370774e4
27 changed files with 423 additions and 294 deletions
3
LICENSE
3
LICENSE
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright 2017-2021 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com
|
Copyright 2017-2024 Max Haniyeu (Azgaar), azgaar.fmg@yandex.com
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
@ -14,6 +14,7 @@ copies or substantial portions of the Software.
|
||||||
|
|
||||||
You can produce, without restrictions, any derivative works from the original
|
You can produce, without restrictions, any derivative works from the original
|
||||||
software and even reap commercial benefits from the sale of the secondary product.
|
software and even reap commercial benefits from the sale of the secondary product.
|
||||||
|
The derivates include created maps, map images, screenshots, videos, and other materials.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
|
|
||||||
46
index.css
46
index.css
|
|
@ -436,6 +436,14 @@ button.options:hover {
|
||||||
margin: 0.8em 0 0 0;
|
margin: 0.8em 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#options .tip {
|
||||||
|
color: #444;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-style: italic;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
#aboutContent {
|
#aboutContent {
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
}
|
}
|
||||||
|
|
@ -733,7 +741,7 @@ input[type="color"]::-webkit-color-swatch-wrapper {
|
||||||
background-color: var(--header-active);
|
background-color: var(--header-active);
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolsContent div {
|
#toolsContent > .grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
margin: 0.2em 0;
|
margin: 0.2em 0;
|
||||||
|
|
@ -757,7 +765,7 @@ input[type="color"]::-webkit-color-swatch-wrapper {
|
||||||
|
|
||||||
#viewMode > button {
|
#viewMode > button {
|
||||||
padding: 0.35em;
|
padding: 0.35em;
|
||||||
margin: 0.2em 0.3em 0.6em 0.3em;
|
margin: 0.3em 0.3em 0.6em 0.3em;
|
||||||
float: left;
|
float: left;
|
||||||
width: 30.7%;
|
width: 30.7%;
|
||||||
}
|
}
|
||||||
|
|
@ -2188,7 +2196,7 @@ svg.button {
|
||||||
#worldControls input[type="number"] {
|
#worldControls input[type="number"] {
|
||||||
border: 1px solid #e5e5e5;
|
border: 1px solid #e5e5e5;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
width: 3.2em;
|
width: 4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#worldControls i.icon-lock-open,
|
#worldControls i.icon-lock-open,
|
||||||
|
|
@ -2247,10 +2255,6 @@ svg.button {
|
||||||
fill: blue;
|
fill: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#globeOutline {
|
|
||||||
fill: url(#temperatureGradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
#globeArea {
|
#globeArea {
|
||||||
fill: white;
|
fill: white;
|
||||||
fill-opacity: 0.3;
|
fill-opacity: 0.3;
|
||||||
|
|
@ -2261,6 +2265,11 @@ svg.button {
|
||||||
stroke-width: 0.2;
|
stroke-width: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#globePrimeMeridian {
|
||||||
|
stroke: blue;
|
||||||
|
stroke-width: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
#globeEquator {
|
#globeEquator {
|
||||||
stroke: red;
|
stroke: red;
|
||||||
stroke-width: 1.4;
|
stroke-width: 1.4;
|
||||||
|
|
@ -2382,6 +2391,29 @@ svg.button {
|
||||||
background: #ccc;
|
background: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #222;
|
||||||
|
margin: 0.8em 0 0 0;
|
||||||
|
}
|
||||||
|
.separator::before,
|
||||||
|
.separator::after {
|
||||||
|
content: "";
|
||||||
|
flex: 1;
|
||||||
|
border-bottom: 1px solid #333;
|
||||||
|
}
|
||||||
|
.separator:not(:empty)::before {
|
||||||
|
margin-right: 0.25em;
|
||||||
|
}
|
||||||
|
.separator:not(:empty)::after {
|
||||||
|
margin-left: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
div,
|
div,
|
||||||
canvas {
|
canvas {
|
||||||
|
|
|
||||||
288
index.html
288
index.html
|
|
@ -138,7 +138,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<link rel="preload" href="index.css?v=1.96.00" 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="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'" />
|
<link rel="preload" href="libs/jquery-ui.css" as="style" onload="this.onload=null; this.rel='stylesheet'" />
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -380,7 +380,7 @@
|
||||||
<rect x="-1%" y="-1%" width="102%" height="102%" fill="url(#oceanic)" />
|
<rect x="-1%" y="-1%" width="102%" height="102%" fill="url(#oceanic)" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg id="loading-rose" width="100%" height="100%" viewBox="0 0 700 700">
|
<svg id="loading-rose" width="100%" height="100%" viewBox="0 0 700 700">
|
||||||
<use href="#rose" x="50%" y="50%" />
|
<use href="#defs-compass-rose" x="50%" y="50%" />
|
||||||
</svg>
|
</svg>
|
||||||
<div id="loading-typography">
|
<div id="loading-typography">
|
||||||
<div id="titleName">Azgaar's</div>
|
<div id="titleName">Azgaar's</div>
|
||||||
|
|
@ -469,9 +469,7 @@
|
||||||
onclick="removePreset()"
|
onclick="removePreset()"
|
||||||
></button>
|
></button>
|
||||||
|
|
||||||
<p data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style">
|
<p>Displayed layers and layers order:</p>
|
||||||
Displayed layers and layers order:
|
|
||||||
</p>
|
|
||||||
<ul
|
<ul
|
||||||
data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style"
|
data-tip="Click to toggle a layer, drag to raise or lower a layer. Ctrl + click to edit layer style"
|
||||||
id="mapLayers"
|
id="mapLayers"
|
||||||
|
|
@ -717,13 +715,15 @@
|
||||||
<li
|
<li
|
||||||
id="toggleVignette"
|
id="toggleVignette"
|
||||||
data-tip="Vignette (border fading): click to toggle. Ctrl + click to edit style"
|
data-tip="Vignette (border fading): click to toggle. Ctrl + click to edit style"
|
||||||
data-shortcut="[ (left bracket)"
|
data-shortcut="[ (left square bracket)"
|
||||||
onclick="toggleVignette(event)"
|
onclick="toggleVignette(event)"
|
||||||
class="solid"
|
class="solid"
|
||||||
>
|
>
|
||||||
Vignette
|
Vignette
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="tip">Click to toggle, drag to raise or lower the layer</div>
|
||||||
|
<div class="tip">Ctrl + click to edit layer style</div>
|
||||||
|
|
||||||
<div id="viewMode" data-tip="Set view node">
|
<div id="viewMode" data-tip="Set view node">
|
||||||
<p>View mode:</p>
|
<p>View mode:</p>
|
||||||
|
|
@ -1317,6 +1317,12 @@
|
||||||
<td><select id="styleStatesBodyFilter" /></td>
|
<td><select id="styleStatesBodyFilter" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr style="margin-top: 0.8em">
|
||||||
|
<td style="font-style: italic">
|
||||||
|
Halo is only rendered if "Rendering" option is set to "Best quality"!
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr data-tip="Set states halo effect width">
|
<tr data-tip="Set states halo effect width">
|
||||||
<td>Halo width</td>
|
<td>Halo width</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -2063,23 +2069,16 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="toolsContent" class="tabcontent">
|
<div id="toolsContent" class="tabcontent">
|
||||||
<p>Click to configure:</p>
|
<div class="separator">Edit</div>
|
||||||
<div>
|
<div class="grid">
|
||||||
<button
|
|
||||||
id="editHeightmapButton"
|
|
||||||
data-tip="Click to open Heightmap customization menu"
|
|
||||||
data-shortcut="Shift + H"
|
|
||||||
>
|
|
||||||
Heightmap
|
|
||||||
</button>
|
|
||||||
<button id="editBiomesButton" data-tip="Click to open Biomes Editor" data-shortcut="Shift + B">
|
<button id="editBiomesButton" data-tip="Click to open Biomes Editor" data-shortcut="Shift + B">
|
||||||
Biomes
|
Biomes
|
||||||
</button>
|
</button>
|
||||||
<button id="editStatesButton" data-tip="Click to open States Editor" data-shortcut="Shift + S">
|
<button id="overviewBurgsButton" data-tip="Click to open Burgs Overview" data-shortcut="Shift + T">
|
||||||
States
|
Burgs
|
||||||
</button>
|
</button>
|
||||||
<button id="editProvincesButton" data-tip="Click to open Provinces Editor" data-shortcut="Shift + P">
|
<button id="editCulturesButton" data-tip="Click to open Cultures Editor" data-shortcut="Shift + C">
|
||||||
Provinces
|
Cultures
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
id="editDiplomacyButton"
|
id="editDiplomacyButton"
|
||||||
|
|
@ -2088,40 +2087,18 @@
|
||||||
>
|
>
|
||||||
Diplomacy
|
Diplomacy
|
||||||
</button>
|
</button>
|
||||||
<button id="editCulturesButton" data-tip="Click to open Cultures Editor" data-shortcut="Shift + C">
|
|
||||||
Cultures
|
|
||||||
</button>
|
|
||||||
<button id="editNamesBaseButton" data-tip="Click to open Namesbase Editor" data-shortcut="Shift + N">
|
|
||||||
Namesbase
|
|
||||||
</button>
|
|
||||||
<button id="editZonesButton" data-tip="Click to open Zones Editor" data-shortcut="Shift + Z">Zones</button>
|
|
||||||
<button id="editReligions" data-tip="Click to open Religions Editor" data-shortcut="Shift + R">
|
|
||||||
Religions
|
|
||||||
</button>
|
|
||||||
<button id="editEmblemButton" data-tip="Click to open Emblem Editor" data-shortcut="Shift + Y">
|
<button id="editEmblemButton" data-tip="Click to open Emblem Editor" data-shortcut="Shift + Y">
|
||||||
Emblems
|
Emblems
|
||||||
</button>
|
</button>
|
||||||
<button id="editUnitsButton" data-tip="Click to open Units Editor" data-shortcut="Shift + Q">Units</button>
|
|
||||||
<button id="editNotesButton" data-tip="Click to open Notes Editor" data-shortcut="Shift + O">Notes</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>Click to overview:</p>
|
|
||||||
<div>
|
|
||||||
<button
|
<button
|
||||||
id="overviewChartsButton"
|
id="editHeightmapButton"
|
||||||
data-tip="Click to open Charts to overview cells data"
|
data-tip="Click to open Heightmap customization menu"
|
||||||
data-shortcut="Shift + A"
|
data-shortcut="Shift + H"
|
||||||
>
|
>
|
||||||
Charts
|
Heightmap
|
||||||
</button>
|
</button>
|
||||||
<button id="overviewBurgsButton" data-tip="Click to open Burgs Overview" data-shortcut="Shift + T">
|
<button id="overviewMarkersButton" data-tip="Click to open Markers Overview" data-shortcut="Shift + K">
|
||||||
Burgs
|
Markers
|
||||||
</button>
|
|
||||||
<button id="overviewRoutesButton" data-tip="Click to open Routes Overview" data-shortcut="Shift + U">
|
|
||||||
Routes
|
|
||||||
</button>
|
|
||||||
<button id="overviewRiversButton" data-tip="Click to open Rivers Overview" data-shortcut="Shift + V">
|
|
||||||
Rivers
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
id="overviewMilitaryButton"
|
id="overviewMilitaryButton"
|
||||||
|
|
@ -2130,41 +2107,58 @@
|
||||||
>
|
>
|
||||||
Military
|
Military
|
||||||
</button>
|
</button>
|
||||||
<button id="overviewMarkersButton" data-tip="Click to open Markers Overview" data-shortcut="Shift + K">
|
<button id="editNamesBaseButton" data-tip="Click to open Namesbase Editor" data-shortcut="Shift + N">
|
||||||
Markers
|
Namesbase
|
||||||
</button>
|
</button>
|
||||||
<button id="overviewCellsButton" data-tip="Click to open Cell details view" data-shortcut="Shift + E">
|
<button id="editNotesButton" data-tip="Click to open Notes Editor" data-shortcut="Shift + O">Notes</button>
|
||||||
Cells
|
<button id="editProvincesButton" data-tip="Click to open Provinces Editor" data-shortcut="Shift + P">
|
||||||
|
Provinces
|
||||||
</button>
|
</button>
|
||||||
|
<button id="editReligions" data-tip="Click to open Religions Editor" data-shortcut="Shift + R">
|
||||||
|
Religions
|
||||||
|
</button>
|
||||||
|
<button id="overviewRiversButton" data-tip="Click to open Rivers Overview" data-shortcut="Shift + V">
|
||||||
|
Rivers
|
||||||
|
</button>
|
||||||
|
<button id="overviewRoutesButton" data-tip="Click to open Routes Overview" data-shortcut="Shift + U">
|
||||||
|
Routes
|
||||||
|
</button>
|
||||||
|
<button id="editStatesButton" data-tip="Click to open States Editor" data-shortcut="Shift + S">
|
||||||
|
States
|
||||||
|
</button>
|
||||||
|
<button id="editUnitsButton" data-tip="Click to open Units Editor" data-shortcut="Shift + Q">Units</button>
|
||||||
|
<button id="editZonesButton" data-tip="Click to open Zones Editor" data-shortcut="Shift + Z">Zones</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Click to regenerate:</p>
|
<div class="separator">Regenerate</div>
|
||||||
<div id="regenerateFeature">
|
<div id="regenerateFeature" class="grid">
|
||||||
|
<button
|
||||||
|
id="regenerateBurgs"
|
||||||
|
data-tip="Click to regenerate all unlocked burgs and routes. States will remain as they are. Note: burgs are only generated in populated areas with culture assigned"
|
||||||
|
>
|
||||||
|
Burgs
|
||||||
|
</button>
|
||||||
|
<button id="regenerateCultures" data-tip="Click to regenerate non-locked cultures">Cultures</button>
|
||||||
|
<button id="regenerateEmblems" data-tip="Click to regenerate all emblems">Emblems</button>
|
||||||
|
<button id="regenerateIce" data-tip="Click to regenerate icebergs and glaciers">Ice</button>
|
||||||
<button
|
<button
|
||||||
id="regenerateStateLabels"
|
id="regenerateStateLabels"
|
||||||
data-tip="Click to update state labels placement based on current borders"
|
data-tip="Click to update state labels placement based on current borders"
|
||||||
>
|
>
|
||||||
Labels
|
Labels
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button id="regenerateMarkers" data-tip="Click to regenerate unlocked markers">
|
||||||
id="regenerateReliefIcons"
|
Markers <i id="configRegenerateMarkers" class="icon-cog" data-tip="Click to set number multiplier"></i>
|
||||||
data-tip="Click to regenerate all relief icons based on current cell biome and elevation"
|
|
||||||
>
|
|
||||||
Relief
|
|
||||||
</button>
|
</button>
|
||||||
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
|
<button
|
||||||
<button id="regenerateRivers" data-tip="Click to regenerate all rivers (restore default state)">
|
id="regenerateMilitary"
|
||||||
Rivers
|
data-tip="Click to recalculate military forces based on current military options"
|
||||||
|
>
|
||||||
|
Military
|
||||||
</button>
|
</button>
|
||||||
<button id="regeneratePopulation" data-tip="Click to recalculate rural and urban population">
|
<button id="regeneratePopulation" data-tip="Click to recalculate rural and urban population">
|
||||||
Population
|
Population
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
id="regenerateStates"
|
|
||||||
data-tip="Click to select new capitals and regenerate non-locked states. Emblems and military forces will be regenerated as well, burgs will remain as they are"
|
|
||||||
>
|
|
||||||
States
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
id="regenerateProvinces"
|
id="regenerateProvinces"
|
||||||
data-tip="Click to regenerate non-locked provinces. States will remain as they are"
|
data-tip="Click to regenerate non-locked provinces. States will remain as they are"
|
||||||
|
|
@ -2172,23 +2166,21 @@
|
||||||
Provinces
|
Provinces
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
id="regenerateBurgs"
|
id="regenerateReliefIcons"
|
||||||
data-tip="Click to regenerate all unlocked burgs and routes. States will remain as they are. Note: burgs are only generated in populated areas with culture assigned"
|
data-tip="Click to regenerate all relief icons based on current cell biome and elevation"
|
||||||
>
|
>
|
||||||
Burgs
|
Relief
|
||||||
</button>
|
</button>
|
||||||
<button id="regenerateEmblems" data-tip="Click to regenerate all emblems">Emblems</button>
|
|
||||||
<button id="regenerateReligions" data-tip="Click to regenerate non-locked religions">Religions</button>
|
<button id="regenerateReligions" data-tip="Click to regenerate non-locked religions">Religions</button>
|
||||||
<button id="regenerateCultures" data-tip="Click to regenerate non-locked cultures">Cultures</button>
|
<button id="regenerateRivers" data-tip="Click to regenerate all rivers (restore default state)">
|
||||||
<button
|
Rivers
|
||||||
id="regenerateMilitary"
|
|
||||||
data-tip="Click to recalculate military forces based on current military options"
|
|
||||||
>
|
|
||||||
Military
|
|
||||||
</button>
|
</button>
|
||||||
<button id="regenerateIce" data-tip="Click to regenerate icebergs and glaciers">Ice</button>
|
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
|
||||||
<button id="regenerateMarkers" data-tip="Click to regenerate unlocked markers">
|
<button
|
||||||
Markers <i id="configRegenerateMarkers" class="icon-cog" data-tip="Click to set number multiplier"></i>
|
id="regenerateStates"
|
||||||
|
data-tip="Click to select new capitals and regenerate non-locked states. Emblems and military forces will be regenerated as well, burgs will remain as they are"
|
||||||
|
>
|
||||||
|
States
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
id="regenerateZones"
|
id="regenerateZones"
|
||||||
|
|
@ -2198,8 +2190,8 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Click to add:</p>
|
<div class="separator">Add</div>
|
||||||
<div id="addFeature">
|
<div id="addFeature" class="grid">
|
||||||
<button
|
<button
|
||||||
id="addBurgTool"
|
id="addBurgTool"
|
||||||
data-tip="Click on map to place a burg. Hold Shift to add multiple"
|
data-tip="Click on map to place a burg. Hold Shift to add multiple"
|
||||||
|
|
@ -2214,14 +2206,6 @@
|
||||||
>
|
>
|
||||||
Label
|
Label
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
id="addRiver"
|
|
||||||
data-tip="Click on map to place a river. Hold Shift to add multiple"
|
|
||||||
data-shortcut="Shift + 3"
|
|
||||||
>
|
|
||||||
River
|
|
||||||
</button>
|
|
||||||
<button id="addRoute" data-tip="Open route creation dialog" data-shortcut="Shift + 4">Route</button>
|
|
||||||
<button
|
<button
|
||||||
id="addMarker"
|
id="addMarker"
|
||||||
data-tip="Click on map to place a marker. Hold Shift to add multiple"
|
data-tip="Click on map to place a marker. Hold Shift to add multiple"
|
||||||
|
|
@ -2229,10 +2213,36 @@
|
||||||
>
|
>
|
||||||
Marker
|
Marker
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
id="addRiver"
|
||||||
|
data-tip="Click on map to place a river. Hold Shift to add multiple"
|
||||||
|
data-shortcut="Shift + 3"
|
||||||
|
>
|
||||||
|
River
|
||||||
|
</button>
|
||||||
|
<<<<<<< HEAD
|
||||||
|
<button id="addRoute" data-tip="Open route creation dialog" data-shortcut="Shift + 4">Route</button>
|
||||||
|
=======
|
||||||
|
<button id="addRoute" data-tip="Click on map to place a route" data-shortcut="Shift + 4">Route</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Click to create a new map:</p>
|
<div class="separator">Show</div>
|
||||||
<div>
|
<div class="grid">
|
||||||
|
<button id="overviewCellsButton" data-tip="Click to open Cell details view" data-shortcut="Shift + E">
|
||||||
|
Cells
|
||||||
|
</button>
|
||||||
|
>>>>>>> 00abd5213b446922a60e2053eaca711a6d4067e2
|
||||||
|
<button
|
||||||
|
id="overviewChartsButton"
|
||||||
|
data-tip="Click to open Charts to overview cells data"
|
||||||
|
data-shortcut="Shift + A"
|
||||||
|
>
|
||||||
|
Charts
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="separator">Create</div>
|
||||||
|
<div class="grid">
|
||||||
<button id="openSubmapMenu" data-tip="Click to generate a submap from the current viewport">Submap</button>
|
<button id="openSubmapMenu" data-tip="Click to generate a submap from the current viewport">Submap</button>
|
||||||
<button id="openResampleMenu" data-tip="Click to transform the map">Transform</button>
|
<button id="openResampleMenu" data-tip="Click to transform the map">Transform</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2321,8 +2331,7 @@
|
||||||
|
|
||||||
<div id="aboutContent" class="tabcontent">
|
<div id="aboutContent" class="tabcontent">
|
||||||
<p>
|
<p>
|
||||||
<a href="https://github.com/Azgaar/Fantasy-Map-Generator" target="_blank">Fantasy Map Generator</a> is a
|
<a href="https://github.com/Azgaar/Fantasy-Map-Generator" target="_blank">Fantasy Map Generator</a> is an
|
||||||
free
|
|
||||||
<a href="https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/LICENSE" target="_blank"
|
<a href="https://github.com/Azgaar/Fantasy-Map-Generator/blob/master/LICENSE" target="_blank"
|
||||||
>open source</a
|
>open source</a
|
||||||
>
|
>
|
||||||
|
|
@ -2341,7 +2350,7 @@
|
||||||
<p>
|
<p>
|
||||||
Join our <a href="https://discordapp.com/invite/X7E84HU" target="_blank">Discord server</a> and
|
Join our <a href="https://discordapp.com/invite/X7E84HU" target="_blank">Discord server</a> and
|
||||||
<a href="https://www.reddit.com/r/FantasyMapGenerator/" target="_blank">Reddit community</a> to ask
|
<a href="https://www.reddit.com/r/FantasyMapGenerator/" target="_blank">Reddit community</a> to ask
|
||||||
questions, get help and share maps.
|
questions, get help and share maps. The created maps can be used for free, even for commercial purposes.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -2539,15 +2548,15 @@
|
||||||
<i data-locked="0" id="lock_mapSize" class="icon-lock-open"></i>
|
<i data-locked="0" id="lock_mapSize" class="icon-lock-open"></i>
|
||||||
<label data-tip="Set map size relative to the world size">
|
<label data-tip="Set map size relative to the world size">
|
||||||
<i>Map size:</i>
|
<i>Map size:</i>
|
||||||
<input id="mapSizeInput" data-stored="mapSize" type="number" 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" />
|
<input id="mapSizeOutput" data-stored="mapSize" type="range" min="1" max="100" step="0.1" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<i data-locked="0" id="lock_latitude" class="icon-lock-open"></i>
|
<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>
|
<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
|
<br /><i>N</i
|
||||||
><input
|
><input
|
||||||
id="latitudeOutput"
|
id="latitudeOutput"
|
||||||
|
|
@ -2555,14 +2564,42 @@
|
||||||
type="range"
|
type="range"
|
||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
step="1"
|
step="0.1"
|
||||||
style="width: 10.3em"
|
style="width: 10.3em"
|
||||||
/><i>S</i>
|
/><i>S</i>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label data-tip="Set precipitation - water amount clouds can bring. Defines rivers and biomes generation">
|
<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"
|
||||||
|
>
|
||||||
<i data-locked="0" id="lock_prec" class="icon-lock-open"></i>
|
<i data-locked="0" id="lock_prec" class="icon-lock-open"></i>
|
||||||
<i>Precipitation:</i>
|
<i>Precipitation:</i>
|
||||||
<input id="precInput" data-stored="prec" type="number" />%
|
<input id="precInput" data-stored="prec" type="number" />%
|
||||||
|
|
@ -2637,8 +2674,10 @@
|
||||||
<text x="-15" y="190">60°</text>
|
<text x="-15" y="190">60°</text>
|
||||||
<text x="-15" y="204">90°</text>
|
<text x="-15" y="204">90°</text>
|
||||||
</g>
|
</g>
|
||||||
<circle id="globeOutline" cx="100" cy="100" r="100" />
|
<circle id="globeGradient" cx="100" cy="100" r="100" fill="url(#temperatureGradient)" stroke="none" />
|
||||||
<line id="globeEquator" x1="1" x2="199" y1="100" y2="100" />
|
<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="globeGraticule" />
|
||||||
<path id="globeArea" />
|
<path id="globeArea" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
@ -2648,6 +2687,14 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 0.3em">
|
||||||
|
<i>Presets:</i>
|
||||||
|
<button id="wcWholeWorld" data-tip="Click to set map size to cover the whole world">Whole world</button>
|
||||||
|
<button id="wcNorthern" data-tip="Click to set map size to cover the Northern latitudes">Northern</button>
|
||||||
|
<button id="wcTropical" data-tip="Click to set map size to cover the Tropical latitudes">Tropical</button>
|
||||||
|
<button id="wcSouthern" data-tip="Click to set map size to cover the Southern latitudes">Southern</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="labelEditor" class="dialog" style="display: none">
|
<div id="labelEditor" class="dialog" style="display: none">
|
||||||
|
|
@ -7894,18 +7941,19 @@
|
||||||
</symbol>
|
</symbol>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g id="rose" stroke-width="1">
|
<g id="defs-compass-rose" stroke-width="1.1">
|
||||||
<g id="sL" stroke="#3f3f3f">
|
<g id="rose-coord-line" stroke="#3f3f3f">
|
||||||
<line id="sL1" x1="0" y1="-20000" x2="0" y2="20000" />
|
<line id="sL1" x1="0" y1="-20000" x2="0" y2="20000" />
|
||||||
<line id="sL2" x1="-20000" y1="0" x2="20000" y2="0" />
|
<line id="sL2" x1="-20000" y1="0" x2="20000" y2="0" />
|
||||||
</g>
|
</g>
|
||||||
<use href="#sL" transform="rotate(45)" />
|
<use href="#rose-coord-line" transform="rotate(45)" />
|
||||||
<use href="#sL" transform="rotate(22.5)" />
|
<use href="#rose-coord-line" transform="rotate(22.5)" />
|
||||||
<use href="#sL" transform="rotate(-22.5)" />
|
<use href="#rose-coord-line" transform="rotate(-22.5)" />
|
||||||
<use href="#sL" transform="rotate(11.25)" />
|
<use href="#rose-coord-line" transform="rotate(11.25)" />
|
||||||
<use href="#sL" transform="rotate(-11.25)" />
|
<use href="#rose-coord-line" transform="rotate(-11.25)" />
|
||||||
<use href="#sL" transform="rotate(56.25)" />
|
<use href="#rose-coord-line" transform="rotate(56.25)" />
|
||||||
<use href="#sL" transform="rotate(-56.25)" />
|
<use href="#rose-coord-line" transform="rotate(-56.25)" />
|
||||||
|
|
||||||
<g stroke-width="8" stroke-opacity="1" shape-rendering="geometricprecision">
|
<g stroke-width="8" stroke-opacity="1" shape-rendering="geometricprecision">
|
||||||
<circle r="9" stroke="#000000" fill="#1b1b1b" />
|
<circle r="9" stroke="#000000" fill="#1b1b1b" />
|
||||||
<circle r="75" stroke="#008000" fill="#ffffff" fill-opacity=".1" />
|
<circle r="75" stroke="#008000" fill="#ffffff" fill-opacity=".1" />
|
||||||
|
|
@ -8136,7 +8184,7 @@
|
||||||
<script src="config/heightmap-templates.js"></script>
|
<script src="config/heightmap-templates.js"></script>
|
||||||
<script src="config/precreated-heightmaps.js"></script>
|
<script src="config/precreated-heightmaps.js"></script>
|
||||||
<script src="modules/heightmap-generator.js?v=1.88.00"></script>
|
<script src="modules/heightmap-generator.js?v=1.88.00"></script>
|
||||||
<script src="modules/ocean-layers.js?v=1.96.00"></script>
|
<script src="modules/ocean-layers.js?v=1.98.04"></script>
|
||||||
<script src="modules/river-generator.js?v=1.89.13"></script>
|
<script src="modules/river-generator.js?v=1.89.13"></script>
|
||||||
<script src="modules/lakes.js"></script>
|
<script src="modules/lakes.js"></script>
|
||||||
<script src="modules/biomes.js"></script>
|
<script src="modules/biomes.js"></script>
|
||||||
|
|
@ -8158,15 +8206,15 @@
|
||||||
<script src="modules/ui/measurers.js?v=1.96.00"></script>
|
<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/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="modules/ui/options.js?v=1.98.04"></script>
|
||||||
<script src="main.js?v=1.97.11"></script>
|
<script src="main.js?v=1.98.01"></script>
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></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/style.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/editors.js?v=1.97.12"></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/tools.js?v=1.97.12"></script>
|
||||||
<script defer src="modules/ui/world-configurator.js?v=1.98.00"></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/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/provinces-editor.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
|
<script defer src="modules/ui/biomes-editor.js?v=1.91.05"></script>
|
||||||
|
|
@ -8204,10 +8252,10 @@
|
||||||
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
|
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
|
||||||
<script defer src="libs/rgbquant.min.js"></script>
|
<script defer src="libs/rgbquant.min.js"></script>
|
||||||
<script defer src="libs/jquery.ui.touch-punch.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/save.js?v=1.98.01"></script>
|
||||||
<script defer src="modules/io/load.js?v=1.97.04"></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/cloud.js?v=1.96.00"></script>
|
||||||
<script defer src="modules/io/export.js?v=1.97.03"></script>
|
<script defer src="modules/io/export.js?v=1.98.05"></script>
|
||||||
|
|
||||||
<!-- Web Components -->
|
<!-- Web Components -->
|
||||||
<script defer src="components/fill-box.js"></script>
|
<script defer src="components/fill-box.js"></script>
|
||||||
|
|
|
||||||
125
main.js
125
main.js
|
|
@ -53,7 +53,7 @@ let biomes = viewbox.append("g").attr("id", "biomes");
|
||||||
let cells = viewbox.append("g").attr("id", "cells");
|
let cells = viewbox.append("g").attr("id", "cells");
|
||||||
let gridOverlay = viewbox.append("g").attr("id", "gridOverlay");
|
let gridOverlay = viewbox.append("g").attr("id", "gridOverlay");
|
||||||
let coordinates = viewbox.append("g").attr("id", "coordinates");
|
let coordinates = viewbox.append("g").attr("id", "coordinates");
|
||||||
let compass = viewbox.append("g").attr("id", "compass");
|
let compass = viewbox.append("g").attr("id", "compass").style("display", "none");
|
||||||
let rivers = viewbox.append("g").attr("id", "rivers");
|
let rivers = viewbox.append("g").attr("id", "rivers");
|
||||||
let terrain = viewbox.append("g").attr("id", "terrain");
|
let terrain = viewbox.append("g").attr("id", "terrain");
|
||||||
let relig = viewbox.append("g").attr("id", "relig");
|
let relig = viewbox.append("g").attr("id", "relig");
|
||||||
|
|
@ -126,6 +126,9 @@ emblems.append("g").attr("id", "burgEmblems");
|
||||||
emblems.append("g").attr("id", "provinceEmblems");
|
emblems.append("g").attr("id", "provinceEmblems");
|
||||||
emblems.append("g").attr("id", "stateEmblems");
|
emblems.append("g").attr("id", "stateEmblems");
|
||||||
|
|
||||||
|
// compass
|
||||||
|
compass.append("use").attr("xlink:href", "#defs-compass-rose");
|
||||||
|
|
||||||
// fogging
|
// fogging
|
||||||
fogging.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
fogging.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
||||||
fogging
|
fogging
|
||||||
|
|
@ -195,10 +198,10 @@ let options = {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mapCoordinates = {}; // map coordinates on globe
|
let mapCoordinates = {}; // map coordinates on globe
|
||||||
let populationRate = +document.getElementById("populationRateInput").value;
|
let populationRate = +byId("populationRateInput").value;
|
||||||
let distanceScale = +document.getElementById("distanceScaleInput").value;
|
let distanceScale = +byId("distanceScaleInput").value;
|
||||||
let urbanization = +document.getElementById("urbanizationInput").value;
|
let urbanization = +byId("urbanizationInput").value;
|
||||||
let urbanDensity = +document.getElementById("urbanDensityInput").value;
|
let urbanDensity = +byId("urbanDensityInput").value;
|
||||||
|
|
||||||
applyStoredOptions();
|
applyStoredOptions();
|
||||||
|
|
||||||
|
|
@ -439,10 +442,10 @@ function handleZoom(isScaleChanged, isPositionChanged) {
|
||||||
|
|
||||||
// zoom image converter overlay
|
// zoom image converter overlay
|
||||||
if (customization === 1) {
|
if (customization === 1) {
|
||||||
const canvas = document.getElementById("canvas");
|
const canvas = byId("canvas");
|
||||||
if (!canvas || canvas.style.opacity === "0") return;
|
if (!canvas || canvas.style.opacity === "0") return;
|
||||||
|
|
||||||
const img = document.getElementById("imageToConvert");
|
const img = byId("imageToConvert");
|
||||||
if (!img) return;
|
if (!img) return;
|
||||||
|
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
@ -524,7 +527,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;
|
||||||
const el = !hidden && document.getElementById(`marker${i}`);
|
const el = !hidden && byId(`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);
|
||||||
|
|
@ -561,18 +564,18 @@ void (function addDragToUpload() {
|
||||||
document.addEventListener("dragover", function (e) {
|
document.addEventListener("dragover", function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
document.getElementById("mapOverlay").style.display = null;
|
byId("mapOverlay").style.display = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener("dragleave", function (e) {
|
document.addEventListener("dragleave", function (e) {
|
||||||
document.getElementById("mapOverlay").style.display = "none";
|
byId("mapOverlay").style.display = "none";
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener("drop", function (e) {
|
document.addEventListener("drop", function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const overlay = document.getElementById("mapOverlay");
|
const overlay = byId("mapOverlay");
|
||||||
overlay.style.display = "none";
|
overlay.style.display = "none";
|
||||||
if (e.dataTransfer.items == null || e.dataTransfer.items.length !== 1) return; // no files or more than one
|
if (e.dataTransfer.items == null || e.dataTransfer.items.length !== 1) return; // no files or more than one
|
||||||
const file = e.dataTransfer.items[0].getAsFile();
|
const file = e.dataTransfer.items[0].getAsFile();
|
||||||
|
|
@ -780,7 +783,7 @@ function addLakesInDeepDepressions() {
|
||||||
TIME && console.time("addLakesInDeepDepressions");
|
TIME && console.time("addLakesInDeepDepressions");
|
||||||
const {cells, features} = grid;
|
const {cells, features} = grid;
|
||||||
const {c, h, b} = cells;
|
const {c, h, b} = cells;
|
||||||
const ELEVATION_LIMIT = +document.getElementById("lakeElevationLimitOutput").value;
|
const ELEVATION_LIMIT = +byId("lakeElevationLimitOutput").value;
|
||||||
if (ELEVATION_LIMIT === 80) return;
|
if (ELEVATION_LIMIT === 80) return;
|
||||||
|
|
||||||
for (const i of cells.i) {
|
for (const i of cells.i) {
|
||||||
|
|
@ -880,73 +883,77 @@ function openNearSeaLakes() {
|
||||||
|
|
||||||
// define map size and position based on template and random factor
|
// define map size and position based on template and random factor
|
||||||
function defineMapSize() {
|
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
|
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("mapSize")) mapSizeOutput.value = mapSizeInput.value = size;
|
||||||
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = rn(latitude);
|
if (randomize || !locked("latitude")) latitudeOutput.value = latitudeInput.value = latitude;
|
||||||
|
if (randomize || !locked("longitude")) longitudeOutput.value = longitudeInput.value = longitude;
|
||||||
|
|
||||||
function getSizeAndLatitude() {
|
function getSizeAndLatitude() {
|
||||||
const template = byId("templateInput").value; // heightmap template
|
const template = byId("templateInput").value; // heightmap template
|
||||||
|
|
||||||
if (template === "africa-centric") return [45, 53];
|
if (template === "africa-centric") return [45, 53, 38];
|
||||||
if (template === "arabia") return [20, 35];
|
if (template === "arabia") return [20, 35, 35];
|
||||||
if (template === "atlantics") return [42, 23];
|
if (template === "atlantics") return [42, 23, 65];
|
||||||
if (template === "britain") return [7, 20];
|
if (template === "britain") return [7, 20, 51.3];
|
||||||
if (template === "caribbean") return [15, 40];
|
if (template === "caribbean") return [15, 40, 74.8];
|
||||||
if (template === "east-asia") return [11, 28];
|
if (template === "east-asia") return [11, 28, 9.4];
|
||||||
if (template === "eurasia") return [38, 19];
|
if (template === "eurasia") return [38, 19, 27];
|
||||||
if (template === "europe") return [20, 16];
|
if (template === "europe") return [20, 16, 44.8];
|
||||||
if (template === "europe-accented") return [14, 22];
|
if (template === "europe-accented") return [14, 22, 44.8];
|
||||||
if (template === "europe-and-central-asia") return [25, 10];
|
if (template === "europe-and-central-asia") return [25, 10, 39.5];
|
||||||
if (template === "europe-central") return [11, 22];
|
if (template === "europe-central") return [11, 22, 46.4];
|
||||||
if (template === "europe-north") return [7, 18];
|
if (template === "europe-north") return [7, 18, 48.9];
|
||||||
if (template === "greenland") return [22, 7];
|
if (template === "greenland") return [22, 7, 55.8];
|
||||||
if (template === "hellenica") return [8, 27];
|
if (template === "hellenica") return [8, 27, 43.5];
|
||||||
if (template === "iceland") return [2, 15];
|
if (template === "iceland") return [2, 15, 55.3];
|
||||||
if (template === "indian-ocean") return [45, 55];
|
if (template === "indian-ocean") return [45, 55, 14];
|
||||||
if (template === "mediterranean-sea") return [10, 29];
|
if (template === "mediterranean-sea") return [10, 29, 45.8];
|
||||||
if (template === "middle-east") return [8, 31];
|
if (template === "middle-east") return [8, 31, 34.4];
|
||||||
if (template === "north-america") return [37, 17];
|
if (template === "north-america") return [37, 17, 87];
|
||||||
if (template === "us-centric") return [66, 27];
|
if (template === "us-centric") return [66, 27, 100];
|
||||||
if (template === "us-mainland") return [16, 30];
|
if (template === "us-mainland") return [16, 30, 77.5];
|
||||||
if (template === "world") return [78, 27];
|
if (template === "world") return [78, 27, 40];
|
||||||
if (template === "world-from-pacific") return [75, 32];
|
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 part = grid.features.some(f => f.land && f.border); // if land goes over map borders
|
||||||
const max = part ? 80 : 100; // max size
|
const max = part ? 80 : 100; // max size
|
||||||
const lat = () => gauss(P(0.5) ? 40 : 60, 20, 25, 75); // latitude shift
|
const lat = () => gauss(P(0.5) ? 40 : 60, 20, 25, 75); // latitude shift
|
||||||
|
|
||||||
if (!part) {
|
if (!part) {
|
||||||
if (template === "Pangea") return [100, 50];
|
if (template === "pangea") return [100, 50, 50];
|
||||||
if (template === "Shattered" && P(0.7)) return [100, 50];
|
if (template === "shattered" && P(0.7)) return [100, 50, 50];
|
||||||
if (template === "Continents" && P(0.5)) return [100, 50];
|
if (template === "continents" && P(0.5)) return [100, 50, 50];
|
||||||
if (template === "Archipelago" && P(0.35)) return [100, 50];
|
if (template === "archipelago" && P(0.35)) return [100, 50, 50];
|
||||||
if (template === "High Island" && P(0.25)) return [100, 50];
|
if (template === "highIsland" && P(0.25)) return [100, 50, 50];
|
||||||
if (template === "Low Island" && P(0.1)) return [100, 50];
|
if (template === "lowIsland" && P(0.1)) return [100, 50, 50];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template === "Pangea") return [gauss(70, 20, 30, max), lat()];
|
if (template === "pangea") return [gauss(70, 20, 30, max), lat(), 50];
|
||||||
if (template === "Volcano") return [gauss(20, 20, 10, max), lat()];
|
if (template === "volcano") return [gauss(20, 20, 10, max), lat(), 50];
|
||||||
if (template === "Mediterranean") return [gauss(25, 30, 15, 80), lat()];
|
if (template === "mediterranean") return [gauss(25, 30, 15, 80), lat(), 50];
|
||||||
if (template === "Peninsula") return [gauss(15, 15, 5, 80), lat()];
|
if (template === "peninsula") return [gauss(15, 15, 5, 80), lat(), 50];
|
||||||
if (template === "Isthmus") return [gauss(15, 20, 3, 80), lat()];
|
if (template === "isthmus") return [gauss(15, 20, 3, 80), lat(), 50];
|
||||||
if (template === "Atoll") return [gauss(5, 10, 2, max), lat()];
|
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
|
// calculate map position on globe
|
||||||
function calculateMapCoordinates() {
|
function calculateMapCoordinates() {
|
||||||
const size = +document.getElementById("mapSizeOutput").value;
|
const sizeFraction = +byId("mapSizeOutput").value / 100;
|
||||||
const latShift = +document.getElementById("latitudeOutput").value;
|
const latShift = +byId("latitudeOutput").value / 100;
|
||||||
|
const lonShift = +byId("longitudeOutput").value / 100;
|
||||||
|
|
||||||
const latT = rn((size / 100) * 180, 1);
|
const latT = rn(sizeFraction * 180, 1);
|
||||||
const latN = rn(90 - ((180 - latT) * latShift) / 100, 1);
|
const latN = rn(90 - (180 - latT) * latShift, 1);
|
||||||
const latS = rn(latN - latT, 1);
|
const latS = rn(latN - latT, 1);
|
||||||
|
|
||||||
const lon = rn(Math.min(((graphWidth / graphHeight) * latT) / 2, 180));
|
const lonT = rn(Math.min((graphWidth / graphHeight) * latT, 360), 1);
|
||||||
mapCoordinates = {latT, latN, latS, lonT: lon * 2, lonW: -lon, lonE: lon};
|
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
|
// temperature model, trying to follow real-world data
|
||||||
|
|
@ -1759,7 +1766,7 @@ function addZones(number = 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEruption() {
|
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;
|
if (!volcano) return;
|
||||||
|
|
||||||
const x = +volcano.dataset.x,
|
const x = +volcano.dataset.x,
|
||||||
|
|
@ -1978,7 +1985,7 @@ function undraw() {
|
||||||
.getElementById("deftemp")
|
.getElementById("deftemp")
|
||||||
.querySelectorAll("path, clipPath, svg")
|
.querySelectorAll("path, clipPath, svg")
|
||||||
.forEach(el => el.remove());
|
.forEach(el => el.remove());
|
||||||
document.getElementById("coas").innerHTML = ""; // remove auto-generated emblems
|
byId("coas").innerHTML = ""; // remove auto-generated emblems
|
||||||
notes = [];
|
notes = [];
|
||||||
rulers = new Rulers();
|
rulers = new Rulers();
|
||||||
unfog();
|
unfog();
|
||||||
|
|
|
||||||
|
|
@ -848,10 +848,23 @@ export function resolveVersionConflicts(version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 1.98) {
|
if (version < 1.98) {
|
||||||
// v1.98.00 changed routes generation algorithm and data format
|
// v1.98.00 changed compass layer and rose element id
|
||||||
|
const rose = compass.select("use");
|
||||||
|
rose.attr("xlink:href", "#defs-compass-rose");
|
||||||
|
|
||||||
|
if (!compass.selectAll("*").size()) {
|
||||||
|
compass.style("display", "none");
|
||||||
|
compass.append("use").attr("xlink:href", "#defs-compass-rose");
|
||||||
|
shiftCompass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version < 1.99) {
|
||||||
|
// v1.99.00 changed routes generation algorithm and data format
|
||||||
// 1. cells.road => cells.routes and now it an object of objects {i1: {i2: routeId, i3: routeId}}
|
// 1. cells.road => cells.routes and now it an object of objects {i1: {i2: routeId, i3: routeId}}
|
||||||
// 2. cells.crossroad is removed
|
// 2. cells.crossroad is removed
|
||||||
// 3. pack.routes is added as an array of objects
|
// 3. pack.routes is added as an array of objects
|
||||||
// 4. rendering is changed
|
// 4. rendering is changed
|
||||||
|
// v1.98.00 changed compass layer and rose element id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,8 @@ function getSettings() {
|
||||||
populationRate: populationRate,
|
populationRate: populationRate,
|
||||||
urbanization: urbanization,
|
urbanization: urbanization,
|
||||||
mapSize: mapSizeOutput.value,
|
mapSize: mapSizeOutput.value,
|
||||||
latitudeO: latitudeOutput.value,
|
latitude: latitudeOutput.value,
|
||||||
|
longitude: longitudeOutput.value,
|
||||||
prec: precOutput.value,
|
prec: precOutput.value,
|
||||||
options: options,
|
options: options,
|
||||||
mapName: mapName.value,
|
mapName: mapName.value,
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ async function exportToPngTiles() {
|
||||||
imgSchema.src = urlSchema;
|
imgSchema.src = urlSchema;
|
||||||
await loadImage(imgSchema);
|
await loadImage(imgSchema);
|
||||||
|
|
||||||
status.innerHTML = "Drawing schema...";
|
status.innerHTML = "Rendering schema...";
|
||||||
ctx.drawImage(imgSchema, 0, 0, canvas.width, canvas.height);
|
ctx.drawImage(imgSchema, 0, 0, canvas.width, canvas.height);
|
||||||
const blob = await canvasToBlob(canvas, "image/png");
|
const blob = await canvasToBlob(canvas, "image/png");
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
@ -95,9 +95,9 @@ async function exportToPngTiles() {
|
||||||
|
|
||||||
// download tiles
|
// download tiles
|
||||||
const url = await getMapURL("tiles", {fullMap: true});
|
const url = await getMapURL("tiles", {fullMap: true});
|
||||||
const tilesX = +byId("tileColsInput").value;
|
const tilesX = +byId("tileColsOutput").value || 2;
|
||||||
const tilesY = +byId("tileRowsInput").value;
|
const tilesY = +byId("tileRowsOutput").value || 2;
|
||||||
const scale = +byId("tileScaleInput").value;
|
const scale = +byId("tileScaleOutput").value || 1;
|
||||||
const tolesTotal = tilesX * tilesY;
|
const tolesTotal = tilesX * tilesY;
|
||||||
|
|
||||||
const tileW = (graphWidth / tilesX) | 0;
|
const tileW = (graphWidth / tilesX) | 0;
|
||||||
|
|
@ -113,11 +113,17 @@ async function exportToPngTiles() {
|
||||||
await loadImage(img);
|
await loadImage(img);
|
||||||
|
|
||||||
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
function getRowLabel(row) {
|
||||||
|
const first = row >= alphabet.length ? alphabet[Math.floor(row / alphabet.length) - 1] : "";
|
||||||
|
const last = alphabet[row % alphabet.length];
|
||||||
|
return first + last;
|
||||||
|
}
|
||||||
|
|
||||||
for (let y = 0, row = 0, id = 1; y + tileH <= graphHeight; y += tileH, row++) {
|
for (let y = 0, row = 0, id = 1; y + tileH <= graphHeight; y += tileH, row++) {
|
||||||
const rowName = alphabet[row % alphabet.length];
|
const rowName = getRowLabel(row);
|
||||||
|
|
||||||
for (let x = 0, cell = 1; x + tileW <= graphWidth; x += tileW, cell++, id++) {
|
for (let x = 0, cell = 1; x + tileW <= graphWidth; x += tileW, cell++, id++) {
|
||||||
status.innerHTML = `Drawing tile ${rowName}${cell} (${id} of ${tolesTotal})...`;
|
status.innerHTML = `Rendering tile ${rowName}${cell} (${id} of ${tolesTotal})...`;
|
||||||
ctx.drawImage(img, x, y, tileW, tileH, 0, 0, width, height);
|
ctx.drawImage(img, x, y, tileW, tileH, 0, 0, width, height);
|
||||||
const blob = await canvasToBlob(canvas, "image/png");
|
const blob = await canvasToBlob(canvas, "image/png");
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
@ -295,7 +301,7 @@ async function getMapURL(type, options) {
|
||||||
|
|
||||||
// add wind rose
|
// add wind rose
|
||||||
if (cloneEl.getElementById("compass")) {
|
if (cloneEl.getElementById("compass")) {
|
||||||
const rose = svgDefs.getElementById("rose");
|
const rose = svgDefs.getElementById("defs-compass-rose");
|
||||||
if (rose) cloneDefs.appendChild(rose.cloneNode(true));
|
if (rose) cloneDefs.appendChild(rose.cloneNode(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,7 @@ async function parseLoadedData(data, mapVersion) {
|
||||||
if (settings[22]) stylePreset.value = settings[22];
|
if (settings[22]) stylePreset.value = settings[22];
|
||||||
if (settings[23]) rescaleLabels.checked = +settings[23];
|
if (settings[23]) rescaleLabels.checked = +settings[23];
|
||||||
if (settings[24]) urbanDensity = urbanDensityInput.value = urbanDensityOutput.value = +settings[24];
|
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() {
|
void (function applyOptionsToUI() {
|
||||||
|
|
@ -458,7 +459,7 @@ async function parseLoadedData(data, mapVersion) {
|
||||||
{
|
{
|
||||||
// dynamically import and run auto-update script
|
// dynamically import and run auto-update script
|
||||||
const versionNumber = parseFloat(params[0]);
|
const versionNumber = parseFloat(params[0]);
|
||||||
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.97.04");
|
const {resolveVersionConflicts} = await import("../dynamic/auto-update.js?v=1.98.00");
|
||||||
resolveVersionConflicts(versionNumber);
|
resolveVersionConflicts(versionNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,8 @@ function prepareMapData() {
|
||||||
+hideLabels.checked,
|
+hideLabels.checked,
|
||||||
stylePreset.value,
|
stylePreset.value,
|
||||||
+rescaleLabels.checked,
|
+rescaleLabels.checked,
|
||||||
urbanDensity
|
urbanDensity,
|
||||||
|
longitudeOutput.value
|
||||||
].join("|");
|
].join("|");
|
||||||
const coords = JSON.stringify(mapCoordinates);
|
const coords = JSON.stringify(mapCoordinates);
|
||||||
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ function toDMS(coord, c) {
|
||||||
const minutes = Math.floor(minutesNotTruncated);
|
const minutes = Math.floor(minutesNotTruncated);
|
||||||
const seconds = Math.floor((minutesNotTruncated - minutes) * 60);
|
const seconds = Math.floor((minutesNotTruncated - minutes) * 60);
|
||||||
const cardinal = c === "lat" ? (coord >= 0 ? "N" : "S") : coord >= 0 ? "E" : "W";
|
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
|
// get surface elevation
|
||||||
|
|
|
||||||
|
|
@ -1070,27 +1070,29 @@ function drawStates() {
|
||||||
|
|
||||||
const bodyData = body.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
|
const bodyData = body.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
|
||||||
const gapData = gap.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
|
const gapData = gap.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
|
||||||
const haloData = halo.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
|
|
||||||
|
|
||||||
const bodyString = bodyData.map(d => `<path id="state${d[1]}" d="${d[0]}" fill="${d[2]}" stroke="none"/>`).join("");
|
const bodyString = bodyData.map(d => `<path id="state${d[1]}" d="${d[0]}" fill="${d[2]}" stroke="none"/>`).join("");
|
||||||
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("");
|
||||||
|
statesBody.html(bodyString + gapString);
|
||||||
|
|
||||||
|
const isOptimized = shapeRendering.value === "optimizeSpeed";
|
||||||
|
if (!isOptimized) {
|
||||||
|
const haloData = halo.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]);
|
||||||
|
|
||||||
|
const haloString = haloData
|
||||||
|
.map(d => {
|
||||||
|
const stroke = d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666";
|
||||||
|
return `<path id="state-border${d[1]}" d="${d[0]}" clip-path="url(#state-clip${d[1]})" stroke="${stroke}"/>`;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
statesHalo.html(haloString);
|
||||||
|
|
||||||
const clipString = bodyData
|
const clipString = bodyData
|
||||||
.map(d => `<clipPath id="state-clip${d[1]}"><use href="#state${d[1]}"/></clipPath>`)
|
.map(d => `<clipPath id="state-clip${d[1]}"><use href="#state${d[1]}"/></clipPath>`)
|
||||||
.join("");
|
.join("");
|
||||||
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"
|
|
||||||
}"/>`
|
|
||||||
)
|
|
||||||
.join("");
|
|
||||||
|
|
||||||
statesBody.html(bodyString + gapString);
|
|
||||||
defs.select("#statePaths").html(clipString);
|
defs.select("#statePaths").html(clipString);
|
||||||
statesHalo.html(haloString);
|
}
|
||||||
|
|
||||||
// connect vertices to chain
|
|
||||||
function connectVertices(start, state) {
|
function connectVertices(start, state) {
|
||||||
const chain = []; // vertices chain to form a path
|
const chain = []; // vertices chain to form a path
|
||||||
const getType = c => {
|
const getType = c => {
|
||||||
|
|
@ -1525,10 +1527,6 @@ function toggleCompass(event) {
|
||||||
if (!layerIsOn("toggleCompass")) {
|
if (!layerIsOn("toggleCompass")) {
|
||||||
turnButtonOn("toggleCompass");
|
turnButtonOn("toggleCompass");
|
||||||
$("#compass").fadeIn();
|
$("#compass").fadeIn();
|
||||||
if (!compass.selectAll("*").size()) {
|
|
||||||
compass.append("use").attr("xlink:href", "#rose");
|
|
||||||
shiftCompass();
|
|
||||||
}
|
|
||||||
if (event && isCtrlClick(event)) editStyle("compass");
|
if (event && isCtrlClick(event)) editStyle("compass");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) {
|
||||||
|
|
|
||||||
|
|
@ -644,17 +644,16 @@ function randomizeCultureSet() {
|
||||||
function setRendering(value) {
|
function setRendering(value) {
|
||||||
viewbox.attr("shape-rendering", value);
|
viewbox.attr("shape-rendering", value);
|
||||||
|
|
||||||
// if (value === "optimizeSpeed") {
|
if (value === "optimizeSpeed") {
|
||||||
// // block some styles
|
// block some styles
|
||||||
// coastline.select("#sea_island").style("filter", "none");
|
coastline.select("#sea_island").style("filter", "none");
|
||||||
// statesHalo.style("display", "none");
|
statesHalo.style("display", "none");
|
||||||
// emblems.style("opacity", 1);
|
} else {
|
||||||
// } else {
|
// remove style block
|
||||||
// // remove style block
|
coastline.select("#sea_island").style("filter", null);
|
||||||
// coastline.select("#sea_island").style("filter", null);
|
statesHalo.style("display", null);
|
||||||
// statesHalo.style("display", null);
|
if (pack.cells && statesHalo.selectAll("*").size() === 0) drawStates();
|
||||||
// emblems.style("opacity", null);
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate current year and era name
|
// generate current year and era name
|
||||||
|
|
@ -902,9 +901,9 @@ function updateTilesOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tileSize = byId("tileSize");
|
const tileSize = byId("tileSize");
|
||||||
const tilesX = +byId("tileColsOutput").value;
|
const tilesX = +byId("tileColsOutput").value || 2;
|
||||||
const tilesY = +byId("tileRowsOutput").value;
|
const tilesY = +byId("tileRowsOutput").value || 2;
|
||||||
const scale = +byId("tileScaleOutput").value;
|
const scale = +byId("tileScaleOutput").value || 1;
|
||||||
|
|
||||||
// calculate size
|
// calculate size
|
||||||
const sizeX = graphWidth * scale * tilesX;
|
const sizeX = graphWidth * scale * tilesX;
|
||||||
|
|
@ -921,11 +920,16 @@ function updateTilesOptions() {
|
||||||
const tileH = (graphHeight / tilesY) | 0;
|
const tileH = (graphHeight / tilesY) | 0;
|
||||||
|
|
||||||
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
function getRowLabel(row) {
|
||||||
|
const first = row >= alphabet.length ? alphabet[Math.floor(row / alphabet.length) - 1] : "";
|
||||||
|
const last = alphabet[row % alphabet.length];
|
||||||
|
return first + last;
|
||||||
|
}
|
||||||
|
|
||||||
for (let y = 0, row = 0; y + tileH <= graphHeight; y += tileH, row++) {
|
for (let y = 0, row = 0; y + tileH <= graphHeight; y += tileH, row++) {
|
||||||
for (let x = 0, column = 1; x + tileW <= graphWidth; x += tileW, column++) {
|
for (let x = 0, column = 1; x + tileW <= graphWidth; x += tileW, column++) {
|
||||||
rects.push(`<rect x=${x} y=${y} width=${tileW} height=${tileH} />`);
|
rects.push(`<rect x=${x} y=${y} width=${tileW} height=${tileH} />`);
|
||||||
const label = alphabet[row % alphabet.length] + column;
|
labels.push(`<text x=${x + tileW / 2} y=${y + tileH / 2}>${getRowLabel(row)}${column}</text>`);
|
||||||
labels.push(`<text x=${x + tileW / 2} y=${y + tileH / 2}>${label}</text>`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ async function getStylePreset(desiredPreset) {
|
||||||
|
|
||||||
async function fetchSystemPreset(preset) {
|
async function fetchSystemPreset(preset) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`./styles/${preset}.json`);
|
const res = await fetch(`./styles/${preset}.json?v=${version}`);
|
||||||
return await res.json();
|
return await res.json();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error("Cannot fetch style preset", preset);
|
throw new Error("Cannot fetch style preset", preset);
|
||||||
|
|
@ -198,7 +198,7 @@ function addStylePreset() {
|
||||||
"mask"
|
"mask"
|
||||||
],
|
],
|
||||||
"#compass": ["opacity", "transform", "filter", "mask", "shape-rendering"],
|
"#compass": ["opacity", "transform", "filter", "mask", "shape-rendering"],
|
||||||
"#rose": ["transform"],
|
"#compass > use": ["transform"],
|
||||||
"#relig": ["opacity", "stroke", "stroke-width", "filter"],
|
"#relig": ["opacity", "stroke", "stroke-width", "filter"],
|
||||||
"#cults": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
|
"#cults": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
|
||||||
"#landmass": ["opacity", "fill", "filter"],
|
"#landmass": ["opacity", "fill", "filter"],
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,17 @@ function editWorld() {
|
||||||
title: "Configure World",
|
title: "Configure World",
|
||||||
resizable: false,
|
resizable: false,
|
||||||
width: "minmax(40em, 85vw)",
|
width: "minmax(40em, 85vw)",
|
||||||
buttons: {
|
buttons: {"Update world": updateWorld},
|
||||||
"Whole World": () => applyWorldPreset(100, 50),
|
|
||||||
Northern: () => applyWorldPreset(33, 25),
|
|
||||||
Tropical: () => applyWorldPreset(33, 50),
|
|
||||||
Southern: () => applyWorldPreset(33, 75)
|
|
||||||
},
|
|
||||||
open: function () {
|
open: function () {
|
||||||
const buttons = $(this).dialog("widget").find(".ui-dialog-buttonset > button");
|
const checkbox = /* html */ `<div class="dontAsk" data-tip="Automatically update world on input changes and button clicks">
|
||||||
buttons[0].addEventListener("mousemove", () => tip("Click to set map size to cover the whole World"));
|
<input id="wcAutoChange" class="checkbox" type="checkbox" checked />
|
||||||
buttons[1].addEventListener("mousemove", () => tip("Click to set map size to cover the Northern latitudes"));
|
<label for="wcAutoChange" class="checkbox-label"><i>auto-apply changes</i></label>
|
||||||
buttons[2].addEventListener("mousemove", () => tip("Click to set map size to cover the Tropical latitudes"));
|
</div>`;
|
||||||
buttons[3].addEventListener("mousemove", () => tip("Click to set map size to cover the Southern latitudes"));
|
const pane = this.parentElement.querySelector(".ui-dialog-buttonpane");
|
||||||
|
pane.insertAdjacentHTML("afterbegin", checkbox);
|
||||||
|
|
||||||
|
const button = this.parentElement.querySelector(".ui-dialog-buttonset > button");
|
||||||
|
button.on("mousemove", () => tip("Apply curreny settings to the map"));
|
||||||
},
|
},
|
||||||
close: function () {
|
close: function () {
|
||||||
$(this).dialog("destroy");
|
$(this).dialog("destroy");
|
||||||
|
|
@ -34,12 +33,17 @@ function editWorld() {
|
||||||
if (modules.editWorld) return;
|
if (modules.editWorld) return;
|
||||||
modules.editWorld = true;
|
modules.editWorld = true;
|
||||||
|
|
||||||
byId("worldControls").addEventListener("input", e => updateWorld(e.target));
|
const graticule = d3.geoGraticule();
|
||||||
globe.select("#globeWindArrows").on("click", changeWind);
|
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();
|
updateWindDirections();
|
||||||
|
|
||||||
byId("restoreWinds").addEventListener("click", restoreDefaultWinds);
|
byId("worldControls").on("input", handleControlsChange);
|
||||||
|
byId("restoreWinds").on("click", restoreDefaultWinds);
|
||||||
|
byId("wcWholeWorld").on("click", () => applyWorldPreset(100, 50));
|
||||||
|
byId("wcNorthern").on("click", () => applyWorldPreset(33, 25));
|
||||||
|
byId("wcTropical").on("click", () => applyWorldPreset(33, 50));
|
||||||
|
byId("wcSouthern").on("click", () => applyWorldPreset(33, 75));
|
||||||
|
|
||||||
function updateInputValues() {
|
function updateInputValues() {
|
||||||
byId("temperatureEquatorInput").value = options.temperatureEquator;
|
byId("temperatureEquatorInput").value = options.temperatureEquator;
|
||||||
|
|
@ -55,27 +59,27 @@ function editWorld() {
|
||||||
byId("temperatureSouthPoleF").innerText = convertTemperature(options.temperatureSouthPole, "°F");
|
byId("temperatureSouthPoleF").innerText = convertTemperature(options.temperatureSouthPole, "°F");
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateWorld(el) {
|
function handleControlsChange({target}) {
|
||||||
if (el?.dataset.stored) {
|
const stored = target.dataset.stored;
|
||||||
const stored = el.dataset.stored;
|
byId(stored + "Input").value = target.value;
|
||||||
byId(stored + "Input").value = el.value;
|
byId(stored + "Output").value = target.value;
|
||||||
byId(stored + "Output").value = el.value;
|
lock(stored);
|
||||||
lock(el.dataset.stored);
|
|
||||||
|
|
||||||
if (stored === "temperatureEquator") {
|
if (stored === "temperatureEquator") {
|
||||||
options.temperatureEquator = Number(el.value);
|
options.temperatureEquator = Number(target.value);
|
||||||
byId("temperatureEquatorF").innerText = convertTemperature(options.temperatureEquator, "°F");
|
byId("temperatureEquatorF").innerText = convertTemperature(options.temperatureEquator, "°F");
|
||||||
}
|
} else if (stored === "temperatureNorthPole") {
|
||||||
if (stored === "temperatureNorthPole") {
|
options.temperatureNorthPole = Number(target.value);
|
||||||
options.temperatureNorthPole = Number(el.value);
|
|
||||||
byId("temperatureNorthPoleF").innerText = convertTemperature(options.temperatureNorthPole, "°F");
|
byId("temperatureNorthPoleF").innerText = convertTemperature(options.temperatureNorthPole, "°F");
|
||||||
}
|
} else if (stored === "temperatureSouthPole") {
|
||||||
if (stored === "temperatureSouthPole") {
|
options.temperatureSouthPole = Number(target.value);
|
||||||
options.temperatureSouthPole = Number(el.value);
|
|
||||||
byId("temperatureSouthPoleF").innerText = convertTemperature(options.temperatureSouthPole, "°F");
|
byId("temperatureSouthPoleF").innerText = convertTemperature(options.temperatureSouthPole, "°F");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (byId("wcAutoChange").checked) updateWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateWorld() {
|
||||||
updateGlobeTemperature();
|
updateGlobeTemperature();
|
||||||
updateGlobePosition();
|
updateGlobePosition();
|
||||||
calculateTemperatures();
|
calculateTemperatures();
|
||||||
|
|
@ -130,6 +134,7 @@ function editWorld() {
|
||||||
[mc.lonW, mc.latN],
|
[mc.lonW, mc.latN],
|
||||||
[mc.lonE, mc.latS]
|
[mc.lonE, mc.latS]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
globe.select("#globeArea").attr("d", round(path(area.outline()))); // map area
|
globe.select("#globeArea").attr("d", round(path(area.outline()))); // map area
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,21 +168,22 @@ function editWorld() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeWind() {
|
function handleWindChange() {
|
||||||
const arrow = d3.event.target.nextElementSibling;
|
const arrow = d3.event.target.nextElementSibling;
|
||||||
const tier = +arrow.dataset.tier;
|
const tier = +arrow.dataset.tier;
|
||||||
options.winds[tier] = (options.winds[tier] + 45) % 360;
|
options.winds[tier] = (options.winds[tier] + 45) % 360;
|
||||||
const tr = parseTransform(arrow.getAttribute("transform"));
|
const tr = parseTransform(arrow.getAttribute("transform"));
|
||||||
arrow.setAttribute("transform", `rotate(${options.winds[tier]} ${tr[1]} ${tr[2]})`);
|
arrow.setAttribute("transform", `rotate(${options.winds[tier]} ${tr[1]} ${tr[2]})`);
|
||||||
localStorage.setItem("winds", options.winds);
|
localStorage.setItem("winds", options.winds);
|
||||||
|
|
||||||
const mapTiers = d3.range(mapCoordinates.latN, mapCoordinates.latS, -30).map(c => ((90 - c) / 30) | 0);
|
const mapTiers = d3.range(mapCoordinates.latN, mapCoordinates.latS, -30).map(c => ((90 - c) / 30) | 0);
|
||||||
if (mapTiers.includes(tier)) updateWorld();
|
if (byId("wcAutoChange").checked && mapTiers.includes(tier)) updateWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreDefaultWinds() {
|
function restoreDefaultWinds() {
|
||||||
const defaultWinds = [225, 45, 225, 315, 135, 315];
|
const defaultWinds = [225, 45, 225, 315, 135, 315];
|
||||||
const mapTiers = d3.range(mapCoordinates.latN, mapCoordinates.latS, -30).map(c => ((90 - c) / 30) | 0);
|
const mapTiers = d3.range(mapCoordinates.latN, mapCoordinates.latS, -30).map(c => ((90 - c) / 30) | 0);
|
||||||
const update = mapTiers.some(t => options.winds[t] != defaultWinds[t]);
|
const update = byId("wcAutoChange").checked && mapTiers.some(t => options.winds[t] != defaultWinds[t]);
|
||||||
options.winds = defaultWinds;
|
options.winds = defaultWinds;
|
||||||
updateWindDirections();
|
updateWindDirections();
|
||||||
if (update) updateWorld();
|
if (update) updateWorld();
|
||||||
|
|
@ -188,6 +194,6 @@ function editWorld() {
|
||||||
byId("latitudeInput").value = byId("latitudeOutput").value = lat;
|
byId("latitudeInput").value = byId("latitudeOutput").value = lat;
|
||||||
lock("mapSize");
|
lock("mapSize");
|
||||||
lock("latitude");
|
lock("latitude");
|
||||||
updateWorld();
|
if (byId("wcAutoChange").checked) updateWorld();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
run_php_server.bat
Normal file
3
run_php_server.bat
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
start chrome.exe http://localhost:3000/
|
||||||
|
@echo off
|
||||||
|
php -S localhost:3000
|
||||||
|
|
@ -72,8 +72,8 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": "translate(80 80) scale(.25)"
|
"transform": "translate(80 80) scale(0.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.7,
|
"opacity": 0.7,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": "translate(80 80) scale(.25)"
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": null
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.7,
|
"opacity": 0.7,
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@
|
||||||
"mask": "",
|
"mask": "",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": null
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.5,
|
"opacity": 0.5,
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": null
|
"transform": "translate(80 80) scale(0.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.7,
|
"opacity": 0.7,
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": "translate(100 100) scale(0.3)"
|
"transform": "translate(100 100) scale(0.3)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": null
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.5,
|
"opacity": 0.5,
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": null
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.7,
|
"opacity": 0.7,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": "translate(80 80) scale(0.25)"
|
"transform": "translate(80 80) scale(0.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": null
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
"opacity": 0.5,
|
"opacity": 0.5,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"mask": "url(#water)",
|
"mask": "url(#water)",
|
||||||
"shape-rendering": "optimizespeed"
|
"shape-rendering": "optimizespeed"
|
||||||
},
|
},
|
||||||
"#rose": {
|
"#compass > use": {
|
||||||
"transform": "translate(80 80) scale(.25)"
|
"transform": "translate(80 80) scale(.25)"
|
||||||
},
|
},
|
||||||
"#relig": {
|
"#relig": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.98.00"; // generator version, update each time
|
const version = "1.99.00"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
@ -28,7 +28,11 @@ const version = "1.98.00"; // generator version, update each time
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<strong>Latest changes:</strong>
|
<strong>Latest changes:</strong>
|
||||||
|
<<<<<<< HEAD
|
||||||
<li>New routes generatation algorithm</li>
|
<li>New routes generatation algorithm</li>
|
||||||
|
=======
|
||||||
|
<li>Configurable longitude</li>
|
||||||
|
>>>>>>> 00abd5213b446922a60e2053eaca711a6d4067e2
|
||||||
<li>Preview villages map</li>
|
<li>Preview villages map</li>
|
||||||
<li>Ability to render ocean heightmap</li>
|
<li>Ability to render ocean heightmap</li>
|
||||||
<li>Scale bar styling features</li>
|
<li>Scale bar styling features</li>
|
||||||
|
|
@ -41,6 +45,10 @@ const version = "1.98.00"; // generator version, update each time
|
||||||
<li>North and South Poles temperature can be set independently</li>
|
<li>North and South Poles temperature can be set independently</li>
|
||||||
<li>More than 70 new heraldic charges</li>
|
<li>More than 70 new heraldic charges</li>
|
||||||
<li>Multi-color heraldic charges support</li>
|
<li>Multi-color heraldic charges support</li>
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
<li>New 3D scene options and improvements</li>
|
||||||
|
>>>>>>> 00abd5213b446922a60e2053eaca711a6d4067e2
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Join our <a href="${discord}" target="_blank">Discord server</a> and <a href="${reddit}" target="_blank">Reddit community</a> to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>
|
<p>Join our <a href="${discord}" target="_blank">Discord server</a> and <a href="${reddit}" target="_blank">Reddit community</a> to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue