feat: slider-input web component

This commit is contained in:
Azgaar 2024-08-19 12:03:31 +02:00
parent 147014f0ff
commit 92243bb48c
18 changed files with 378 additions and 375 deletions

View file

@ -0,0 +1,76 @@
{
const style = /* css */ `
slider-input {
display: flex;
align-items: center;
gap: .4em;
}
`;
const styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
styleElement.innerHTML = style;
document.head.appendChild(styleElement);
}
{
const template = document.createElement("template");
template.innerHTML = /* html */ `
<input type="range" />
<input type="number" />
`;
class SliderInput extends HTMLElement {
constructor() {
super();
this.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
const range = this.querySelector("input[type=range]");
const number = this.querySelector("input[type=number]");
range.value = number.value = this.getAttribute("value") || 50;
range.min = number.min = this.getAttribute("min") || 0;
range.max = number.max = this.getAttribute("max") || 100;
range.step = number.step = this.getAttribute("step") || 1;
range.addEventListener("input", this.handleEvent.bind(this));
number.addEventListener("input", this.handleEvent.bind(this));
range.addEventListener("change", this.handleEvent.bind(this));
number.addEventListener("change", this.handleEvent.bind(this));
}
handleEvent(e) {
const range = this.querySelector("input[type=range]");
const number = this.querySelector("input[type=number]");
this.value = range.value = number.value = e.target.value;
this.dispatchEvent(
new CustomEvent(e.type, {
detail: {value: e.target.value},
bubbles: true,
composed: true
})
);
}
set value(value) {
const range = this.querySelector("input[type=range]");
const number = this.querySelector("input[type=number]");
range.value = number.value = value;
}
get value() {
const number = this.querySelector("input[type=number]");
return number.value;
}
get valueAsNumber() {
const number = this.querySelector("input[type=number]");
return number.valueAsNumber;
}
}
customElements.define("slider-input", SliderInput);
}

107
index.css
View file

@ -525,7 +525,48 @@ input[type="color"]::-webkit-color-swatch-wrapper {
font-size: smaller;
}
#options input[type="text"] {
border: 0px;
width: 62%;
font-size: smaller;
}
#options output {
text-align: right;
font-size: smaller;
}
#options input[type="number"] {
font-size: 0.8em;
border: 0;
text-align: right;
background-color: transparent;
width: 3.3em;
}
#options input[type="number"]::-webkit-inner-spin-button,
#options input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
#options input[type="number"]:hover {
outline: 1px solid var(--dark-solid);
}
#options input.paired {
text-align: center;
background-color: white;
}
#options input.long {
width: 100%;
background-color: white;
text-align: left;
}
#options input[type="range"] {
width: 100%;
height: 8px;
background: 0;
appearance: none;
@ -568,55 +609,7 @@ input[type="color"]::-webkit-color-swatch-wrapper {
height: 2px;
}
#options input[type="number"] {
font-size: 0.8em;
}
#options input[type="text"] {
border: 0px;
width: 62%;
font-size: smaller;
}
#optionsContent output {
text-align: right;
font-size: smaller;
}
#optionsContent input[type="number"] {
border: 0;
text-align: right;
background-color: transparent;
width: 3.3em;
-moz-appearance: textfield;
}
#optionsContent input[type="number"]::-webkit-inner-spin-button,
#optionsContent input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
#optionsContent input[type="number"]:hover {
outline: 1px solid var(--dark-solid);
}
#optionsContent input.paired {
text-align: center;
background-color: white;
}
#optionsContent input.long {
width: 100%;
background-color: white;
text-align: left;
}
#optionsContent input[type="range"] {
width: 100%;
}
#optionsContent select {
#options select {
width: 100%;
}
@ -641,19 +634,6 @@ input[type="color"]::-webkit-color-swatch-wrapper {
transform: translate(0px, 1px);
}
#styleElements input[type="range"] {
width: 64%;
}
#styleElements select {
width: 64%;
}
#styleElements input[type="number"] {
width: 6em;
border: 0;
}
#styleSelectFont > option {
font-size: 2em;
}
@ -724,9 +704,6 @@ input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0.45em 0.75em;
margin: 0.35em 0;
transition: 0.1s;
font-size: 1em;
text-transform: capitalize;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

View file

@ -836,27 +836,24 @@
</td>
</tr>
<tr data-tip="Terracing rate. Set to 0 (toggle off) to improve performance">
<tr data-tip="Terracing power. Set to 0 to toggle off">
<td>Terracing</td>
<td>
<input id="styleHeightmapTerracingInput" type="range" min="0" max="20" step="1" />
<output id="styleHeightmapTerracingOutput">0</output>
<slider-input id="styleHeightmapTerracing" min="0" max="20" step="1"></slider-input>
</td>
</tr>
<tr data-tip="Layers reduction rate. Increase to improve performance">
<td>Reduce layers</td>
<td>
<input id="styleHeightmapSkipInput" type="range" min="0" max="10" step="1" value="5" />
<output id="styleHeightmapSkipOutput">5</output>
<slider-input id="styleHeightmapSkip" min="0" max="10" step="1"></slider-input>
</td>
</tr>
<tr data-tip="Line simplification rate. Increase to slightly improve performance">
<td>Simplify line</td>
<td>
<input id="styleHeightmapSimplificationInput" type="range" min="0" max="10" step="1" value="0" />
<output id="styleHeightmapSimplificationOutput">0</output>
<slider-input id="styleHeightmapSimplification" min="0" max="10" step="1"></slider-input>
</td>
</tr>
@ -874,7 +871,7 @@
<tr data-tip="Select color scheme for the element">
<td>Color scheme</td>
<td>
<select id="styleHeightmapScheme"></select>
<select id="styleHeightmapScheme" style="width: 86%"></select>
<button
id="openCreateHeightmapSchemeButton"
data-tip="Click to add a custom heightmap color scheme"
@ -889,8 +886,7 @@
<tr data-tip="Set opacity. 0: transparent, 1: solid">
<td>Opacity</td>
<td>
<input id="styleOpacityInput" type="range" min="0" max="1" step="0.01" value=".4" />
<output id="styleOpacityOutput">0.4</output>
<slider-input id="styleOpacityInput" min="0" max="1" step="0.01"></slider-input>
</td>
</tr>
</tbody>
@ -899,8 +895,7 @@
<tr data-tip="Set maximum number of items in one column">
<td>Column items</td>
<td>
<input id="styleLegendColItems" type="range" min="1" max="30" step="1" value="8" />
<output id="styleLegendColItemsOutput">8</output>
<slider-input id="styleLegendColItems" min="1" max="30" step="1"></slider-input>
</td>
</tr>
@ -915,8 +910,7 @@
<tr data-tip="Set background opacity">
<td>Opacity</td>
<td>
<input id="styleLegendOpacity" type="range" min="0" max="1" step="0.01" value="1" />
<output id="styleLegendOpacityOutput">1</output>
<slider-input id="styleLegendOpacity" min="0" max="1" step=".01"></slider-input>
</td>
</tr>
</tbody>
@ -943,7 +937,7 @@
<tr data-tip="Select texture image. Big textures can highly affect performance">
<td>Image</td>
<td>
<select id="styleTextureInput">
<select id="styleTextureInput" style="width: 86%">
<option value="">No texture</option>
<option value="./images/textures/folded-paper-big.jpg">Folded paper big</option>
<option value="./images/textures/folded-paper-small.jpg">Folded paper small</option>
@ -1027,8 +1021,7 @@
<tr data-tip="Set vignette blue propagation (in pixels)">
<td>Blur</td>
<td>
<input id="styleVignetteBlur" type="range" min="0" max="400" step="1" value="50" />
<output id="styleVignetteBlurOutput">50</output>px
<slider-input id="styleVignetteBlur" min="0" max="400" step="1"></slider-input>
</td>
</tr>
</tbody>
@ -1053,8 +1046,7 @@
<tr data-tip="Set ocean pattern opacity">
<td>Pattern opacity</td>
<td>
<input id="styleOceanPatternOpacity" type="range" min="0" max="1" step=".01" value=".2" />
<output id="styleOceanPatternOpacityOutput">0.2</output>
<slider-input id="styleOceanPatternOpacity" min="0" max="1" step=".01"></slider-input>
</td>
</tr>
@ -1118,8 +1110,7 @@
<tr data-tip="Set wind (compass) rose size">
<td>Size</td>
<td>
<input id="styleCompassSizeInput" type="range" min=".02" max="1" step=".01" value=".25" />
<output id="styleCompassSizeOutput">.25</output>
<slider-input id="styleCompassSizeInput" min=".02" max="1" step=".01"></slider-input>
</td>
</tr>
@ -1147,8 +1138,7 @@
<tr data-tip="Define the size of relief icons. All relief icons will be regenerated">
<td>Size</td>
<td>
<input id="styleReliefSizeInput" data-stored="reliefSize" type="range" min=".2" max="4" step=".01" />
<output id="styleReliefSizeOutput"></output>
<slider-input id="styleReliefSize" min=".2" max="4" step=".01"></slider-input>
</td>
</tr>
@ -1157,23 +1147,14 @@
>
<td>Density</td>
<td>
<input
id="styleReliefDensityInput"
data-stored="reliefDensity"
type="range"
min=".3"
max=".8"
step=".01"
value=".4"
/>
<output id="styleReliefDensityOutput">.4</output>
<slider-input id="styleReliefDensity" min=".3" max=".8" step=".01"></slider-input>
</td>
</tr>
</tbody>
<tbody id="styleFill">
<tr data-tip="Set fill color">
<td>Fill</td>
<td>Fill color</td>
<td>
<input id="styleFillInput" type="color" value="#5E4FA2" />
<output id="styleFillOutput">#5E4FA2</output>
@ -1183,7 +1164,7 @@
<tbody id="styleStroke">
<tr data-tip="Set stroke color">
<td>Stroke</td>
<td>Stroke color</td>
<td>
<input id="styleStrokeInput" type="color" value="#5E4FA2" />
<output id="styleStrokeOutput">#5E4FA2</output>
@ -1195,8 +1176,7 @@
<tr data-tip="Set stroke width">
<td>Stroke width</td>
<td>
<input id="styleStrokeWidthInput" type="range" min="0" max="5" step=".01" value="1" />
<output id="styleStrokeWidthOutput">1</output>
<slider-input id="styleStrokeWidthInput" min="0" max="5" step=".01"></slider-input>
</td>
</tr>
</tbody>
@ -1229,7 +1209,7 @@
<tr data-tip="Select font">
<td>Font</td>
<td>
<select id="styleSelectFont"></select>
<select id="styleSelectFont" style="width: 85%"></select>
<button id="styleFontAdd" data-tip="Add a font" class="icon-plus sideButton"></button>
</td>
</tr>
@ -1241,7 +1221,7 @@
<td>
<button id="styleFontPlus" data-tip="Increase font" class="whiteButton">+</button>
<button id="styleFontMinus" data-tip="Descrease font" class="whiteButton">-</button>
<input id="styleFontSize" type="number" min=".5" max="100" step=".1" value="14" />
<input id="styleFontSize" type="number" min=".5" max="100" step=".1" />
</td>
</tr>
</tbody>
@ -1281,16 +1261,14 @@
<tr data-tip="Define transparency of temperature leyer. Set to 0 to make it fully transparent">
<td>Fill opacity</td>
<td>
<input id="styleTemperatureFillOpacityInput" type="range" min="0" max="1" step=".01" value=".3" />
<output id="styleTemperatureFillOpacityOutput">0.3</output>
<slider-input id="styleTemperatureFillOpacityInput" min="0" max="1" step=".01"></slider-input>
</td>
</tr>
<tr data-tip="Set labels size">
<td>Labels size</td>
<td>
<input id="styleTemperatureFontSizeInput" type="range" min="0" max="30" value="8" />
<output id="styleTemperatureFontSizeOutput">8</output>
<slider-input id="styleTemperatureFontSizeInput" min="0" max="30" step="1"></slider-input>
</td>
</tr>
@ -1307,8 +1285,7 @@
<tr data-tip="Set states fill opacity. 0: invisible, 1: solid">
<td>Body opacity</td>
<td>
<input id="styleStatesBodyOpacity" type="range" min="0" max="1" step="0.01" />
<output id="styleStatesBodyOpacityOutput"></output>
<slider-input id="styleStatesBodyOpacity" min="0" max="1" step="0.01"></slider-input>
</td>
</tr>
@ -1326,24 +1303,21 @@
<tr data-tip="Set states halo effect width">
<td>Halo width</td>
<td>
<input id="styleStatesHaloWidth" type="range" min="0" max="30" step=".1" value="10" />
<output id="styleStatesHaloWidthOutput">10</output>
<slider-input id="styleStatesHaloWidth" min="0" max="30" step="0.1"></slider-input>
</td>
</tr>
<tr data-tip="Set states halo effect opacity. 0: invisible, 1: solid">
<td>Halo opacity</td>
<td>
<input id="styleStatesHaloOpacity" type="range" min="0" max="1" step="0.01" value="1" />
<output id="styleStatesHaloOpacityOutput">1</output>
<slider-input id="styleStatesHaloOpacity" min="0" max="1" step="0.01"></slider-input>
</td>
</tr>
<tr data-tip="Select halo effect power (blur). Set to 0 to make it solid line" style="margin-bottom: 1em">
<td>Halo blur</td>
<td>
<input id="styleStatesHaloBlur" type="range" min="0" max="10" step="0.01" value="4" />
<output id="styleStatesHaloBlurOutput">4</output>
<slider-input id="styleStatesHaloBlur" min="0" max="10" step="0.01"></slider-input>
</td>
</tr>
</tbody>
@ -1352,22 +1326,20 @@
<tr data-tip="Set fill transparency. Set to 0 to make it fully transparent">
<td>Fill opacity</td>
<td>
<input id="styleArmiesFillOpacity" type="range" min="0" max="1" step=".01" value="1" />
<output id="styleArmiesFillOpacityOutput">1</output>
<slider-input id="styleArmiesFillOpacity" min="0" max="1" step=".01"></slider-input>
</td>
</tr>
<tr data-tip="Set regiment box size. All regiments will be redrawn on change (position will defaulted)">
<td>Box Size</td>
<td>
<input id="styleArmiesSize" type="range" min="1" max="10" step=".1" value="3" />
<output id="styleArmiesSizeOutput">3</output>
<slider-input id="styleArmiesSize" min="0" max="10" step=".1"></slider-input>
</td>
</tr>
</tbody>
<tbody id="styleEmblems">
<tr data-tip="Set state emblems size multiplier">
<td>State Size</td>
<td>State size</td>
<td>
<input
id="emblemsStateSizeInput"
@ -1382,7 +1354,7 @@
</tr>
<tr data-tip="Set province emblems size multiplier">
<td>Province Size</td>
<td>Province size</td>
<td>
<input
id="emblemsProvinceSizeInput"
@ -1397,7 +1369,7 @@
</tr>
<tr data-tip="Set burg emblems size multiplier">
<td>Burg Size</td>
<td>Burg size</td>
<td>
<input
id="emblemsBurgSizeInput"
@ -1495,15 +1467,14 @@
<tr data-tip="Set background opacity. 0: transparent, 1: solid">
<td>Back opacity</td>
<td>
<input id="styleScaleBarBackgroundOpacityInput" type="range" min="0" max="1" step="0.01" />
<output id="styleScaleBarBackgroundOpacityOutput"></output>
<slider-input id="styleScaleBarBackgroundOpacity" min="0" max="1" step=".01"></slider-input>
</td>
</tr>
<tr data-tip="Set background fill color">
<td>Back fill</td>
<td>
<input id="styleScaleBarBackgroundFillInput" type="color" />
<input id="styleScaleBarBackgroundFill" type="color" />
<output id="styleScaleBarBackgroundFillOutput"></output>
</td>
</tr>
@ -1511,7 +1482,7 @@
<tr data-tip="Set background stroke color and width">
<td>Back stroke</td>
<td>
<input id="styleScaleBarBackgroundStrokeInput" type="color" />
<input id="styleScaleBarBackgroundStroke" type="color" />
<output id="styleScaleBarBackgroundStrokeOutput"></output>
<span>Width </span>
@ -1712,53 +1683,41 @@
<tr data-tip="Define how many states and capitals should be generated">
<td>
<i data-locked="0" id="lock_regions" class="icon-lock-open"></i>
<i data-locked="0" id="lock_statesNumber" class="icon-lock-open"></i>
</td>
<td>States number</td>
<td>
<input id="regionsInput" data-stored="regions" type="range" min="0" max="99" value="13" />
</td>
<td>
<input id="regionsOutput" data-stored="regions" type="number" min="0" max="999" value="13" />
<td colspan="2">
<slider-input id="statesNumber" data-stored="statesNumber" min="0" max="100"></slider-input>
</td>
</tr>
<tr data-tip="Define burgs percentage to form a separate province">
<td>
<i data-locked="0" id="lock_provinces" class="icon-lock-open"></i>
<i data-locked="0" id="lock_provincesRatio" class="icon-lock-open"></i>
</td>
<td>Provinces ratio</td>
<td>
<input id="provincesInput" data-stored="provinces" type="range" min="0" max="100" value="30" />
</td>
<td>
<input id="provincesOutput" data-stored="provinces" type="number" min="0" max="100" value="30" />
<td colspan="2">
<slider-input id="provincesRatio" data-stored="provincesRatio" min="0" max="100"></slider-input>
</td>
</tr>
<tr data-tip="Define how much states and cultures can vary in size. Defines expansionism value">
<td>
<i data-locked="0" id="lock_power" class="icon-lock-open"></i>
<i data-locked="0" id="lock_sizeVariety" class="icon-lock-open"></i>
</td>
<td>Size variety</td>
<td>
<input id="powerInput" data-stored="power" type="range" min="0" max="10" step=".2" value="5" />
</td>
<td>
<input id="powerOutput" data-stored="power" type="number" min="0" max="10" step=".1" value="5" />
<td colspan="2">
<slider-input id="sizeVariety" data-stored="sizeVariety" min="0" max="10" step=".1"></slider-input>
</td>
</tr>
<tr data-tip="Set state and cultures growth rate. Defines how many lands will stay neutral">
<td>
<i data-locked="0" id="lock_neutral" class="icon-lock-open"></i>
<i data-locked="0" id="lock_growthRate" class="icon-lock-open"></i>
</td>
<td>Growth rate</td>
<td>
<input id="neutralInput" data-stored="neutral" type="range" min=".1" max="2" step=".1" value="1" />
</td>
<td>
<input id="neutralOutput" data-stored="neutral" type="number" min=".1" max="2" step=".1" value="1" />
<td colspan="2">
<slider-input id="growthRate" data-stored="growthRate" min=".1" max="2" step=".1"></slider-input>
</td>
</tr>
@ -1779,14 +1738,17 @@
data-tip="Define how many organized religions and cults should be generated. Cultures will have their own folk religions in any case"
>
<td>
<i data-locked="0" id="lock_religions" class="icon-lock-open"></i>
<i data-locked="0" id="lock_religionsNumber" class="icon-lock-open"></i>
</td>
<td>Religions number</td>
<td>
<input id="religionsInput" data-stored="religions" type="range" min="0" max="50" step="1" value="15" />
</td>
<td>
<output id="religionsOutput" data-stored="religions" value="auto"></output>
<td colspan="2">
<slider-input
id="religionsNumber"
data-stored="religionsNumber"
min="0"
max="50"
step="1"
></slider-input>
</td>
</tr>
@ -1815,22 +1777,16 @@
>
<td></td>
<td>Interface size</td>
<td>
<input id="uiSizeInput" data-stored="uiSize" type="range" min=".6" max="3" step=".1" />
</td>
<td>
<input id="uiSizeOutput" data-stored="uiSize" type="number" min=".6" max="3" step=".1" />
<td colspan="2">
<slider-input id="uiSize" data-stored="uiSize" min=".6" max="3" step=".1"></slider-input>
</td>
</tr>
<tr data-tip="Set tooltip size">
<td></td>
<td>Tooltip size</td>
<td>
<input id="tooltipSizeInput" data-stored="tooltipSize" type="range" min="4" max="32" value="14" />
</td>
<td>
<input id="tooltipSizeOutput" data-stored="tooltipSize" type="number" min="0" max="256" value="14" />
<td colspan="2">
<slider-input id="tooltipSize" data-stored="tooltipSize" min="1" max="32" value="14"></slider-input>
</td>
</tr>
@ -1850,11 +1806,8 @@
<tr data-tip="Set dialog and tool windows transparency">
<td></td>
<td>Transparency</td>
<td>
<input id="transparencyInput" data-stored="transparency" type="range" min="0" max="100" />
</td>
<td>
<input id="transparencyOutput" data-stored="transparency" type="number" min="0" max="100" />
<td colspan="2">
<slider-input id="transparencyInput" data-stored="transparency" min="0" max="100"></slider-input>
</td>
</tr>
@ -8154,6 +8107,9 @@
</defs>
</svg>
<script src="components/fill-box.js"></script>
<script src="components/slider-input.js"></script>
<script src="libs/jquery-3.1.1.min.js"></script>
<script src="libs/jquery-ui.min.js"></script>
<script src="versioning.js"></script>
@ -8254,8 +8210,5 @@
<script defer src="modules/io/load.js?v=1.99.01"></script>
<script defer src="modules/io/cloud.js?v=1.99.00"></script>
<script defer src="modules/io/export.js?v=1.99.00"></script>
<!-- Web Components -->
<script defer src="components/fill-box.js"></script>
</body>
</html>

View file

@ -24,7 +24,7 @@ window.BurgsAndStates = (() => {
function placeCapitals() {
TIME && console.time("placeCapitals");
let count = +regionsOutput.value;
let count = +byId("statesNumber").value;
let burgs = [0];
const rand = () => 0.5 + Math.random() * 0.5;
@ -85,7 +85,7 @@ window.BurgsAndStates = (() => {
b.capital = 1;
// states data
const expansionism = rn(Math.random() * powerInput.value + 1, 1);
const expansionism = rn(Math.random() * byId("sizeVariety").value + 1, 1);
const basename = b.name.length < 9 && each5th(b.cell) ? b.name : Names.getCultureShort(b.culture);
const name = Names.getState(basename, b.culture);
const type = cultures[b.culture].type;
@ -378,7 +378,7 @@ window.BurgsAndStates = (() => {
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
const cost = [];
const globalNeutralRate = byId("neutralInput")?.valueAsNumber || 1;
const globalNeutralRate = byId("growthRate").valueAsNumber || 1;
const statesNeutralRate = byId("statesNeutral")?.valueAsNumber || 1;
const neutral = (cells.i.length / 2) * globalNeutralRate * statesNeutralRate; // limit cost for state growth
@ -975,9 +975,8 @@ window.BurgsAndStates = (() => {
});
}
const percentage = +provincesInput.value;
const max = percentage == 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** 0.5; // max growth
const provincesRatio = +byId("provincesRatio").value;
const max = provincesRatio == 100 ? 1000 : gauss(20, 5, 5, 100) * provincesRatio ** 0.5; // max growth
const forms = {
Monarchy: {County: 22, Earldom: 6, Shire: 2, Landgrave: 2, Margrave: 2, Barony: 2, Captaincy: 1, Seneschalty: 1},
@ -1000,7 +999,7 @@ window.BurgsAndStates = (() => {
.sort((a, b) => b.population * gauss(1, 0.2, 0.5, 1.5, 3) - a.population)
.sort((a, b) => b.capital - a.capital);
if (stateBurgs.length < 2) return; // at least 2 provinces are required
const provincesNumber = Math.max(Math.ceil((stateBurgs.length * percentage) / 100), 2);
const provincesNumber = Math.max(Math.ceil((stateBurgs.length * provincesRatio) / 100), 2);
const form = Object.assign({}, forms[s.form]);

View file

@ -169,7 +169,7 @@ window.Cultures = (function () {
else if (type === "Nomadic") base = 1.5;
else if (type === "Hunting") base = 0.7;
else if (type === "Highland") base = 1.2;
return rn(((Math.random() * powerInput.value) / 2 + 1) * base, 1);
return rn(((Math.random() * byId("sizeVariety").value) / 2 + 1) * base, 1);
}
TIME && console.timeEnd("generateCultures");

View file

@ -728,7 +728,7 @@ function showStatesChart() {
.sum(d => d.area)
.sort((a, b) => b.value - a.value);
const size = 150 + 200 * uiSizeOutput.value;
const size = 150 + 200 * uiSize.value;
const margin = {top: 0, right: -50, bottom: 0, left: -50};
const w = size - margin.left - margin.right;
const h = size - margin.top - margin.bottom;

View file

@ -1,7 +1,7 @@
"use strict";
window.ReliefIcons = (function () {
const ReliefIcons = function () {
const draw = function () {
TIME && console.time("drawRelief");
terrain.selectAll("*").remove();
@ -124,5 +124,5 @@ window.ReliefIcons = (function () {
return "#relief-" + getOldIcon(type) + "-1"; // simple
}
return ReliefIcons;
return {draw};
})();

View file

@ -457,7 +457,7 @@ window.Religions = (function () {
const lockedReligions = pack.religions?.filter(r => r.i && r.lock && !r.removed) || [];
const folkReligions = generateFolkReligions();
const organizedReligions = generateOrganizedReligions(+religionsInput.value, lockedReligions);
const organizedReligions = generateOrganizedReligions(+religionsNumber.value, lockedReligions);
const namedReligions = specifyReligions([...folkReligions, ...organizedReligions]);
const indexedReligions = combineReligions(namedReligions, lockedReligions);
@ -698,7 +698,8 @@ window.Religions = (function () {
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
const cost = [];
const maxExpansionCost = (cells.i.length / 20) * neutralInput.value; // limit cost for organized religions growth
// limit cost for organized religions growth
const maxExpansionCost = (cells.i.length / 20) * byId("growthRate").valueAsNumber;
religions
.filter(r => r.i && !r.lock && r.type !== "Folk" && !r.removed)

View file

@ -317,7 +317,7 @@ function editBiomes() {
}
function regenerateIcons() {
ReliefIcons();
ReliefIcons.draw();
if (!layerIsOn("toggleRelief")) toggleRelief();
}

View file

@ -340,8 +340,8 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
.sum(d => d.population)
.sort((a, b) => b.value - a.value);
const width = 150 + 200 * uiSizeOutput.value;
const height = 150 + 200 * uiSizeOutput.value;
const width = 150 + 200 * uiSize.value;
const height = 150 + 200 * uiSize.value;
const margin = {top: 0, right: -50, bottom: -10, left: -50};
const w = width - margin.left - margin.right;
const h = height - margin.top - margin.bottom;

View file

@ -516,13 +516,14 @@ function fitLegendBox() {
// draw legend with the same data, but using different settings
function redrawLegend() {
if (!legend.select("rect").size()) return;
const name = legend.select("#legendLabel").text();
const data = legend
.attr("data")
.split("|")
.map(l => l.split(","));
drawLegend(name, data);
if (legend.select("rect").size()) {
const name = legend.select("#legendLabel").text();
const data = legend
.attr("data")
.split("|")
.map(l => l.split(","));
drawLegend(name, data);
}
}
function dragLegendBox() {

View file

@ -90,7 +90,7 @@ function editHeightmap(options) {
if (!sessionStorage.getItem("noExitButtonAnimation")) {
sessionStorage.setItem("noExitButtonAnimation", true);
exitCustomization.style.opacity = 0;
const width = 12 * uiSizeOutput.value * 11;
const width = 12 * uiSize.value * 11;
exitCustomization.style.right = (svgWidth - width) / 2 + "px";
exitCustomization.style.bottom = svgHeight / 2 + "px";
exitCustomization.style.transform = "scale(2)";

View file

@ -93,7 +93,7 @@ function restoreCustomPresets() {
// run on map generation
function applyPreset() {
const preset = localStorage.getItem("preset") || document.getElementById("layersPreset").value;
const preset = localStorage.getItem("preset") || byId("layersPreset").value;
changePreset(preset);
}
@ -113,12 +113,12 @@ function changePreset(preset) {
const isDefault = getDefaultPresets()[preset];
removePresetButton.style.display = isDefault ? "none" : "inline-block";
savePresetButton.style.display = "none";
if (document.getElementById("canvas3d")) setTimeout(ThreeD.update(), 400);
if (byId("canvas3d")) setTimeout(ThreeD.update(), 400);
}
function savePreset() {
prompt("Please provide a preset name", {default: ""}, preset => {
presets[preset] = Array.from(document.getElementById("mapLayers").querySelectorAll("li:not(.buttonoff)"))
presets[preset] = Array.from(byId("mapLayers").querySelectorAll("li:not(.buttonoff)"))
.map(node => node.id)
.sort();
layersPreset.add(new Option(preset, preset, false, true));
@ -143,7 +143,7 @@ function removePreset() {
}
function getCurrentPreset() {
const layers = Array.from(document.getElementById("mapLayers").querySelectorAll("li:not(.buttonoff)"))
const layers = Array.from(byId("mapLayers").querySelectorAll("li:not(.buttonoff)"))
.map(node => node.id)
.sort();
const defaultPresets = getDefaultPresets();
@ -174,7 +174,7 @@ function restoreLayers() {
if (layerIsOn("togglePrec")) drawPrec();
if (layerIsOn("togglePopulation")) drawPopulation();
if (layerIsOn("toggleBiomes")) drawBiomes();
if (layerIsOn("toggleRelief")) ReliefIcons();
if (layerIsOn("toggleRelief")) ReliefIcons.draw();
if (layerIsOn("toggleCultures")) drawCultures();
if (layerIsOn("toggleProvinces")) drawProvinces();
if (layerIsOn("toggleReligions")) drawReligions();
@ -1516,8 +1516,8 @@ function drawCoordinates() {
// conver svg point into viewBox point
function getViewPoint(x, y) {
const view = document.getElementById("viewbox");
const svg = document.getElementById("map");
const view = byId("viewbox");
const svg = byId("map");
const pt = svg.createSVGPoint();
(pt.x = x), (pt.y = y);
return pt.matrixTransform(view.getScreenCTM().inverse());
@ -1541,7 +1541,7 @@ function toggleCompass(event) {
function toggleRelief(event) {
if (!layerIsOn("toggleRelief")) {
turnButtonOn("toggleRelief");
if (!terrain.selectAll("*").size()) ReliefIcons();
if (!terrain.selectAll("*").size()) ReliefIcons.draw();
$("#terrain").fadeIn();
if (event && isCtrlClick(event)) editStyle("terrain");
} else {
@ -1907,21 +1907,21 @@ function drawEmblems() {
const getStateEmblemsSize = () => {
const startSize = minmax((graphHeight + graphWidth) / 40, 10, 100);
const statesMod = 1 + validStates.length / 100 - (15 - validStates.length) / 200; // states number modifier
const sizeMod = +document.getElementById("emblemsStateSizeInput").value || 1;
const sizeMod = +byId("emblemsStateSizeInput").value || 1;
return rn((startSize / statesMod) * sizeMod); // target size ~50px on 1536x754 map with 15 states
};
const getProvinceEmblemsSize = () => {
const startSize = minmax((graphHeight + graphWidth) / 100, 5, 70);
const provincesMod = 1 + validProvinces.length / 1000 - (115 - validProvinces.length) / 1000; // states number modifier
const sizeMod = +document.getElementById("emblemsProvinceSizeInput").value || 1;
const sizeMod = +byId("emblemsProvinceSizeInput").value || 1;
return rn((startSize / provincesMod) * sizeMod); // target size ~20px on 1536x754 map with 115 provinces
};
const getBurgEmblemSize = () => {
const startSize = minmax((graphHeight + graphWidth) / 185, 2, 50);
const burgsMod = 1 + validBurgs.length / 1000 - (450 - validBurgs.length) / 1000; // states number modifier
const sizeMod = +document.getElementById("emblemsBurgSizeInput").value || 1;
const sizeMod = +byId("emblemsBurgSizeInput").value || 1;
return rn((startSize / burgsMod) * sizeMod); // target size ~8.5px on 1536x754 map with 450 burgs
};
@ -2020,17 +2020,17 @@ function toggleVignette(event) {
}
function layerIsOn(el) {
const buttonoff = document.getElementById(el).classList.contains("buttonoff");
const buttonoff = byId(el).classList.contains("buttonoff");
return !buttonoff;
}
function turnButtonOff(el) {
document.getElementById(el).classList.add("buttonoff");
byId(el).classList.add("buttonoff");
getCurrentPreset();
}
function turnButtonOn(el) {
document.getElementById(el).classList.remove("buttonoff");
byId(el).classList.remove("buttonoff");
getCurrentPreset();
}

View file

@ -66,12 +66,18 @@ document
.querySelectorAll(".tabcontent")
.forEach(e => (e.style.display = "none"));
if (id === "layersTab") layersContent.style.display = "block";
else if (id === "styleTab") styleContent.style.display = "block";
else if (id === "optionsTab") optionsContent.style.display = "block";
else if (id === "toolsTab")
if (id === "layersTab") {
layersContent.style.display = "block";
} else if (id === "styleTab") {
styleContent.style.display = "block";
selectStyleElement();
} else if (id === "optionsTab") {
optionsContent.style.display = "block";
} else if (id === "toolsTab") {
customization === 1 ? (customizationMenu.style.display = "block") : (toolsContent.style.display = "block");
else if (id === "aboutTab") aboutContent.style.display = "block";
} else if (id === "aboutTab") {
aboutContent.style.display = "block";
}
});
// show popup with a list of Patreon supportes (updated manually)
@ -125,9 +131,9 @@ optionsContent.addEventListener("input", event => {
if (id === "mapWidthInput" || id === "mapHeightInput") mapSizeInputChange();
else if (id === "pointsInput") changeCellsDensity(+value);
else if (id === "culturesSet") changeCultureSet();
else if (id === "regionsInput" || id === "regionsOutput") changeStatesNumber(value);
else if (id === "statesNumber") changeStatesNumber(value);
else if (id === "emblemShape") changeEmblemShape(value);
else if (id === "tooltipSizeInput" || id === "tooltipSizeOutput") changeTooltipSize(value);
else if (id === "tooltipSize") changeTooltipSize(value);
else if (id === "themeHueInput") changeThemeHue(value);
else if (id === "themeColorInput") changeDialogsTheme(themeColorInput.value, transparencyInput.value);
else if (id === "transparencyInput") changeDialogsTheme(themeColorInput.value, value);
@ -137,7 +143,7 @@ optionsContent.addEventListener("change", event => {
const {id, value} = event.target;
if (id === "zoomExtentMin" || id === "zoomExtentMax") changeZoomExtent(value);
else if (id === "optionsSeed") generateMapWithSeed("seed change");
else if (id === "uiSizeInput" || id === "uiSizeOutput") changeUiSize(value);
else if (id === "uiSize") changeUiSize(+value);
else if (id === "shapeRendering") setRendering(value);
else if (id === "yearInput") changeYear();
else if (id === "eraInput") changeEra();
@ -389,18 +395,18 @@ function changeEmblemShape(emblemShape) {
}
function changeStatesNumber(value) {
regionsOutput.style.color = +value ? null : "#b12117";
byId("statesNumber").style.color = +value ? null : "#b12117";
burgLabels.select("#capitals").attr("data-size", Math.max(rn(6 - value / 20), 3));
labels.select("#countries").attr("data-size", Math.max(rn(18 - value / 6), 4));
}
function changeUiSize(value) {
if (isNaN(+value) || +value < 0.5) return;
if (isNaN(value) || value < 0.5) return;
const max = getUImaxSize();
if (+value > max) value = max;
if (value > max) value = max;
uiSizeInput.value = uiSizeOutput.value = value;
uiSize.value = value;
document.getElementsByTagName("body")[0].style.fontSize = rn(value * 10, 2) + "px";
byId("options").style.width = value * 300 + "px";
}
@ -427,7 +433,7 @@ function changeThemeHue(hue) {
// change color and transparency for modal windows
function changeDialogsTheme(themeColor, transparency) {
transparencyInput.value = transparencyOutput.value = transparency;
transparencyInput.value = transparency;
const alpha = (100 - +transparency) / 100;
const alphaReduced = Math.min(alpha + 0.3, 1);
@ -489,11 +495,11 @@ function resetLanguage() {
if (!languageSelect.value) return;
languageSelect.value = "en";
languageSelect.dispatchEvent(new Event("change"));
languageSelect.handleChange(new Event("change"));
// do once again to actually reset the language
languageSelect.value = "en";
languageSelect.dispatchEvent(new Event("change"));
languageSelect.handleChange(new Event("change"));
}
function changeZoomExtent(value) {
@ -560,8 +566,8 @@ function applyStoredOptions() {
if (stored("tooltipSize")) changeTooltipSize(stored("tooltipSize"));
if (stored("regions")) changeStatesNumber(stored("regions"));
uiSizeInput.max = uiSizeOutput.max = getUImaxSize();
if (stored("uiSize")) changeUiSize(stored("uiSize"));
uiSize.max = uiSize.max = getUImaxSize();
if (stored("uiSize")) changeUiSize(+stored("uiSize"));
else changeUiSize(minmax(rn(mapWidthInput.value / 1280, 1), 1, 2.5));
// search params overwrite stored and default options
@ -586,15 +592,15 @@ function randomizeOptions() {
// 'Options' settings
if (randomize || !locked("points")) changeCellsDensity(4); // reset to default, no need to randomize
if (randomize || !locked("template")) randomizeHeightmapTemplate();
if (randomize || !locked("regions")) regionsInput.value = regionsOutput.value = gauss(18, 5, 2, 30);
if (randomize || !locked("provinces")) provincesInput.value = provincesOutput.value = gauss(20, 10, 20, 100);
if (randomize || !locked("statesNumber")) statesNumber.value = gauss(18, 5, 2, 30);
if (randomize || !locked("provincesRatio")) provincesRatio.value = gauss(20, 10, 20, 100);
if (randomize || !locked("manors")) {
manorsInput.value = 1000;
manorsOutput.value = "auto";
}
if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(6, 3, 2, 10);
if (randomize || !locked("power")) powerInput.value = powerOutput.value = gauss(4, 2, 0, 10, 2);
if (randomize || !locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1);
if (randomize || !locked("religionsNumber")) religionsNumber.value = gauss(6, 3, 2, 10);
if (randomize || !locked("sizeVariety")) sizeVariety.value = gauss(4, 2, 0, 10, 1);
if (randomize || !locked("growthRate")) growthRate.value = rn(1 + Math.random(), 1);
if (randomize || !locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30);
if (randomize || !locked("culturesSet")) randomizeCultureSet();

View file

@ -628,8 +628,8 @@ function editProvinces() {
.parentId(d => d.state)(data)
.sum(d => d.area);
const width = 300 + 300 * uiSizeOutput.value,
height = 90 + 90 * uiSizeOutput.value;
const width = 300 + 300 * uiSize.value,
height = 90 + 90 * uiSize.value;
const margin = {top: 10, right: 10, bottom: 0, left: 10};
const w = width - margin.left - margin.right;
const h = height - margin.top - margin.bottom;

View file

@ -72,6 +72,7 @@ function getColorScheme(scheme = "bright") {
// Toggle style sections on element select
styleElementSelect.addEventListener("change", selectStyleElement);
function selectStyleElement() {
const styleElement = styleElementSelect.value;
let el = d3.select("#" + styleElement);
@ -92,7 +93,7 @@ function selectStyleElement() {
// opacity
if (!["landmass", "ocean", "regions", "legend"].includes(styleElement)) {
styleOpacity.style.display = "block";
styleOpacityInput.value = styleOpacityOutput.value = el.attr("opacity") || 1;
styleOpacityInput.value = el.attr("opacity") || 1;
}
// filter
@ -129,7 +130,7 @@ function selectStyleElement() {
styleStroke.style.display = "block";
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke");
styleStrokeWidth.style.display = "block";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
styleStrokeWidthInput.value = el.attr("stroke-width") || 0;
}
// stroke dash
@ -176,9 +177,9 @@ function selectStyleElement() {
styleHeightmapRenderOcean.checked = +el.attr("data-render");
styleHeightmapScheme.value = el.attr("scheme");
styleHeightmapTerracingInput.value = styleHeightmapTerracingOutput.value = el.attr("terracing");
styleHeightmapSkipInput.value = styleHeightmapSkipOutput.value = el.attr("skip");
styleHeightmapSimplificationInput.value = styleHeightmapSimplificationOutput.value = el.attr("relax");
styleHeightmapTerracing.value = el.attr("terracing");
styleHeightmapSkip.value = el.attr("skip");
styleHeightmapSimplification.value = el.attr("relax");
styleHeightmapCurve.value = el.attr("curve");
}
@ -201,13 +202,13 @@ function selectStyleElement() {
const tr = parseTransform(compass.select("use").attr("transform"));
styleCompassShiftX.value = tr[0];
styleCompassShiftY.value = tr[1];
styleCompassSizeInput.value = styleCompassSizeOutput.value = tr[2];
styleCompassSizeInput.value = tr[2];
}
if (styleElement === "terrain") {
styleRelief.style.display = "block";
styleReliefSizeOutput.innerHTML = styleReliefSizeInput.value = terrain.attr("size");
styleReliefDensityOutput.innerHTML = styleReliefDensityInput.value = terrain.attr("density");
styleReliefSize.value = terrain.attr("size") || 1;
styleReliefDensity.value = terrain.attr("density") || 0.4;
styleReliefSet.value = terrain.attr("set");
}
@ -220,17 +221,16 @@ function selectStyleElement() {
.select("#urban")
.attr("stroke");
styleStrokeWidth.style.display = "block";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
styleStrokeWidthInput.value = el.attr("stroke-width") || 0;
}
if (styleElement === "regions") {
styleStates.style.display = "block";
styleStatesBodyOpacity.value = styleStatesBodyOpacityOutput.value = statesBody.attr("opacity") || 1;
styleStatesBodyOpacity.value = statesBody.attr("opacity") || 1;
styleStatesBodyFilter.value = statesBody.attr("filter") || "";
styleStatesHaloWidth.value = styleStatesHaloWidthOutput.value = statesHalo.attr("data-width") || 10;
styleStatesHaloOpacity.value = styleStatesHaloOpacityOutput.value = statesHalo.attr("opacity") || 1;
const blur = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0;
styleStatesHaloBlur.value = styleStatesHaloBlurOutput.value = blur;
styleStatesHaloWidth.value = statesHalo.attr("data-width") || 10;
styleStatesHaloOpacity.value = statesHalo.attr("opacity") || 1;
styleStatesHaloBlur.value = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0;
}
if (styleElement === "labels") {
@ -243,7 +243,7 @@ function selectStyleElement() {
styleVisibility.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#3e3e4b";
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3a3a3a";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 0;
styleStrokeWidthInput.value = el.attr("stroke-width") || 0;
styleShadowInput.value = el.style("text-shadow") || "white 0 0 4px";
styleFont.style.display = "block";
@ -258,7 +258,7 @@ function selectStyleElement() {
styleFont.style.display = "block";
styleSelectFont.value = el.attr("font-family");
styleFontSize.value = el.attr("data-size");
styleFontSize.value = el.attr("font-size");
}
if (styleElement == "burgIcons") {
@ -269,7 +269,7 @@ function selectStyleElement() {
styleRadius.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 0.24;
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24;
styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || "";
styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit";
styleRadiusInput.value = el.attr("size") || 1;
@ -282,7 +282,7 @@ function selectStyleElement() {
styleIconSize.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill") || "#ffffff";
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#3e3e4b";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 0.24;
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.24;
styleIconSizeInput.value = el.attr("size") || 2;
}
@ -292,12 +292,13 @@ function selectStyleElement() {
styleSize.style.display = "block";
styleLegend.style.display = "block";
styleLegendColItemsOutput.value = styleLegendColItems.value = el.attr("data-columns");
styleLegendBackOutput.value = styleLegendBack.value = el.select("#legendBox").attr("fill");
styleLegendOpacityOutput.value = styleLegendOpacity.value = el.select("#legendBox").attr("fill-opacity");
styleLegendColItems.value = el.attr("data-columns");
const legendBox = el.select("#legendBox");
styleLegendBack.value = styleLegendBackOutput.value = legendBox.size() ? legendBox.attr("fill") : "#ffffff";
styleLegendOpacity.value = legendBox.size() ? legendBox.attr("fill-opacity") : 1;
styleStrokeInput.value = styleStrokeOutput.value = el.attr("stroke") || "#111111";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 0.5;
styleStrokeWidthInput.value = el.attr("stroke-width") || 0.5;
styleFont.style.display = "block";
styleSelectFont.value = el.attr("font-family");
@ -308,18 +309,17 @@ function selectStyleElement() {
styleOcean.style.display = "block";
styleOceanFill.value = styleOceanFillOutput.value = oceanLayers.select("#oceanBase").attr("fill");
styleOceanPattern.value = byId("oceanicPattern")?.getAttribute("href");
styleOceanPatternOpacity.value = styleOceanPatternOpacityOutput.value =
byId("oceanicPattern").getAttribute("opacity") || 1;
styleOceanPatternOpacity.value = byId("oceanicPattern").getAttribute("opacity") || 1;
outlineLayers.value = oceanLayers.attr("layers");
}
if (styleElement === "temperature") {
styleStrokeWidth.style.display = "block";
styleTemperature.style.display = "block";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
styleTemperatureFillOpacityInput.value = styleTemperatureFillOpacityOutput.value = el.attr("fill-opacity") || 0.1;
styleStrokeWidthInput.value = el.attr("stroke-width") || "";
styleTemperatureFillOpacityInput.value = el.attr("fill-opacity") || 0.1;
styleTemperatureFillInput.value = styleTemperatureFillOutput.value = el.attr("fill") || "#000";
styleTemperatureFontSizeInput.value = styleTemperatureFontSizeOutput.value = el.attr("font-size") || "8px";
styleTemperatureFontSizeInput.value = el.attr("font-size") || "8px";
}
if (styleElement === "coordinates") {
@ -329,14 +329,14 @@ function selectStyleElement() {
if (styleElement === "armies") {
styleArmies.style.display = "block";
styleArmiesFillOpacity.value = styleArmiesFillOpacityOutput.value = el.attr("fill-opacity");
styleArmiesSize.value = styleArmiesSizeOutput.value = el.attr("box-size");
styleArmiesFillOpacity.value = el.attr("fill-opacity");
styleArmiesSize.value = el.attr("box-size");
}
if (styleElement === "emblems") {
styleEmblems.style.display = "block";
styleStrokeWidth.style.display = "block";
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || 1;
styleStrokeWidthInput.value = el.attr("stroke-width") || 1;
}
// update group options
@ -372,11 +372,9 @@ function selectStyleElement() {
const scaleBarBack = el.select("#scaleBarBack");
if (scaleBarBack.size()) {
styleScaleBarBackgroundOpacityInput.value = styleScaleBarBackgroundOpacityOutput.value =
scaleBarBack.attr("opacity");
styleScaleBarBackgroundFillInput.value = styleScaleBarBackgroundFillOutput.value = scaleBarBack.attr("fill");
styleScaleBarBackgroundStrokeInput.value = styleScaleBarBackgroundStrokeOutput.value =
scaleBarBack.attr("stroke");
styleScaleBarBackgroundOpacity.value = scaleBarBack.attr("opacity");
styleScaleBarBackgroundFill.value = styleScaleBarBackgroundFillOutput.value = scaleBarBack.attr("fill");
styleScaleBarBackgroundStroke.value = styleScaleBarBackgroundStrokeOutput.value = scaleBarBack.attr("stroke");
styleScaleBarBackgroundStrokeWidth.value = scaleBarBack.attr("stroke-width");
styleScaleBarBackgroundFilter.value = scaleBarBack.attr("filter");
styleScaleBarBackgroundPaddingTop.value = scaleBarBack.attr("data-top");
@ -398,7 +396,7 @@ function selectStyleElement() {
styleVignetteHeight.value = digit(maskRect.getAttribute("height"));
styleVignetteRx.value = digit(maskRect.getAttribute("rx"));
styleVignetteRy.value = digit(maskRect.getAttribute("ry"));
styleVignetteBlur.value = styleVignetteBlurOutput.value = digit(maskRect.getAttribute("filter"));
styleVignetteBlur.value = digit(maskRect.getAttribute("filter"));
}
}
}
@ -424,9 +422,8 @@ styleStrokeInput.addEventListener("input", function () {
if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
});
styleStrokeWidthInput.addEventListener("input", function () {
styleStrokeWidthOutput.value = this.value;
getEl().attr("stroke-width", +this.value);
styleStrokeWidthInput.addEventListener("input", e => {
getEl().attr("stroke-width", e.target.value);
if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
});
@ -440,9 +437,8 @@ styleStrokeLinecapInput.addEventListener("change", function () {
if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
});
styleOpacityInput.addEventListener("input", function () {
styleOpacityOutput.value = this.value;
getEl().attr("opacity", this.value);
styleOpacityInput.addEventListener("input", e => {
getEl().attr("opacity", e.target.value);
});
styleFilterInput.addEventListener("change", function () {
@ -537,9 +533,8 @@ styleOceanPattern.addEventListener("change", function () {
byId("oceanicPattern")?.setAttribute("href", this.value);
});
styleOceanPatternOpacity.addEventListener("input", function () {
byId("oceanicPattern").setAttribute("opacity", this.value);
styleOceanPatternOpacityOutput.value = this.value;
styleOceanPatternOpacity.addEventListener("input", e => {
byId("oceanicPattern").setAttribute("opacity", e.target.value);
});
outlineLayers.addEventListener("change", function () {
@ -672,81 +667,74 @@ openCreateHeightmapSchemeButton.addEventListener("click", function () {
});
});
styleHeightmapRenderOcean.addEventListener("change", function () {
getEl().attr("data-render", +this.checked);
styleHeightmapRenderOcean.addEventListener("change", e => {
const checked = +e.target.checked;
getEl().attr("data-render", checked);
drawHeightmap();
});
styleHeightmapTerracingInput.addEventListener("input", function () {
getEl().attr("terracing", this.value);
styleHeightmapTerracing.addEventListener("input", e => {
getEl().attr("terracing", e.target.value);
drawHeightmap();
});
styleHeightmapSkipInput.addEventListener("input", function () {
getEl().attr("skip", this.value);
styleHeightmapSkip.addEventListener("input", e => {
getEl().attr("skip", e.target.value);
drawHeightmap();
});
styleHeightmapSimplificationInput.addEventListener("input", function () {
getEl().attr("relax", this.value);
styleHeightmapSimplification.addEventListener("input", e => {
getEl().attr("relax", e.target.value);
drawHeightmap();
});
styleHeightmapCurve.addEventListener("change", function () {
getEl().attr("curve", this.value);
styleHeightmapCurve.addEventListener("change", e => {
getEl().attr("curve", e.target.value);
drawHeightmap();
});
styleReliefSet.addEventListener("change", function () {
terrain.attr("set", this.value);
ReliefIcons();
styleReliefSet.addEventListener("change", e => {
terrain.attr("set", e.target.value);
ReliefIcons.draw();
if (!layerIsOn("toggleRelief")) toggleRelief();
});
styleReliefSizeInput.addEventListener("change", function () {
terrain.attr("size", this.value);
styleReliefSizeOutput.value = this.value;
ReliefIcons();
styleReliefSize.addEventListener("change", e => {
terrain.attr("size", e.target.value);
ReliefIcons.draw();
if (!layerIsOn("toggleRelief")) toggleRelief();
});
styleReliefDensityInput.addEventListener("change", function () {
terrain.attr("density", this.value);
styleReliefDensityOutput.value = this.value;
ReliefIcons();
styleReliefDensity.addEventListener("change", e => {
terrain.attr("density", e.target.value);
ReliefIcons.draw();
if (!layerIsOn("toggleRelief")) toggleRelief();
});
styleTemperatureFillOpacityInput.addEventListener("input", function () {
temperature.attr("fill-opacity", this.value);
styleTemperatureFillOpacityOutput.value = this.value;
styleTemperatureFillOpacityInput.addEventListener("input", e => {
temperature.attr("fill-opacity", e.target.value);
});
styleTemperatureFontSizeInput.addEventListener("input", function () {
temperature.attr("font-size", this.value + "px");
styleTemperatureFontSizeOutput.value = this.value + "px";
styleTemperatureFontSizeInput.addEventListener("input", e => {
temperature.attr("font-size", e.target.value + "px");
});
styleTemperatureFillInput.addEventListener("input", function () {
temperature.attr("fill", this.value);
styleTemperatureFillOutput.value = this.value;
styleTemperatureFillInput.addEventListener("input", e => {
temperature.attr("fill", e.target.value);
styleTemperatureFillOutput.value = e.target.value;
});
stylePopulationRuralStrokeInput.addEventListener("input", function () {
stylePopulationRuralStrokeInput.addEventListener("input", e => {
population.select("#rural").attr("stroke", this.value);
stylePopulationRuralStrokeOutput.value = this.value;
});
stylePopulationUrbanStrokeInput.addEventListener("input", function () {
stylePopulationUrbanStrokeInput.addEventListener("input", e => {
population.select("#urban").attr("stroke", this.value);
stylePopulationUrbanStrokeOutput.value = this.value;
});
styleCompassSizeInput.addEventListener("input", function () {
styleCompassSizeOutput.value = this.value;
shiftCompass();
});
styleCompassSizeInput.addEventListener("input", shiftCompass);
styleCompassShiftX.addEventListener("input", shiftCompass);
styleCompassShiftY.addEventListener("input", shiftCompass);
@ -755,20 +743,18 @@ function shiftCompass() {
compass.select("use").attr("transform", tr);
}
styleLegendColItems.addEventListener("input", function () {
styleLegendColItemsOutput.value = this.value;
legend.select("#legendBox").attr("data-columns", this.value);
styleLegendColItems.addEventListener("input", e => {
legend.select("#legendBox").attr("data-columns", e.target.value);
redrawLegend();
});
styleLegendBack.addEventListener("input", function () {
styleLegendBackOutput.value = this.value;
legend.select("#legendBox").attr("fill", this.value);
styleLegendBack.addEventListener("input", e => {
styleLegendBackOutput.value = e.target.value;
legend.select("#legendBox").attr("fill", e.target.value);
});
styleLegendOpacity.addEventListener("input", function () {
styleLegendOpacityOutput.value = this.value;
legend.select("#legendBox").attr("fill-opacity", this.value);
styleLegendOpacity.addEventListener("input", e => {
legend.select("#legendBox").attr("fill-opacity", e.target.value);
});
styleSelectFont.addEventListener("change", changeFont);
@ -829,13 +815,13 @@ styleFontSize.addEventListener("change", function () {
});
styleFontPlus.addEventListener("click", function () {
const size = +getEl().attr("data-size") + 1;
changeFontSize(getEl(), Math.min(size, 999));
const current = +styleFontSize.value || 12;
changeFontSize(getEl(), Math.min(current + 1, 999));
});
styleFontMinus.addEventListener("click", function () {
const size = +getEl().attr("data-size") - 1;
changeFontSize(getEl(), Math.max(size, 1));
const current = +styleFontSize.value || 12;
changeFontSize(getEl(), Math.max(current - 1, 1));
});
function changeFontSize(el, size) {
@ -921,39 +907,37 @@ function changeIconSize(size, group) {
styleIconSizeInput.value = size;
}
styleStatesBodyOpacity.addEventListener("input", function () {
styleStatesBodyOpacityOutput.value = this.value;
statesBody.attr("opacity", this.value);
styleStatesBodyOpacity.addEventListener("input", e => {
statesBody.attr("opacity", e.target.value);
});
styleStatesBodyFilter.addEventListener("change", function () {
statesBody.attr("filter", this.value);
});
styleStatesHaloWidth.addEventListener("input", function () {
styleStatesHaloWidthOutput.value = this.value;
statesHalo.attr("data-width", this.value).attr("stroke-width", this.value);
styleStatesHaloWidth.addEventListener("input", e => {
const value = e.target.value;
statesHalo.attr("data-width", value).attr("stroke-width", value);
});
styleStatesHaloOpacity.addEventListener("input", function () {
styleStatesHaloOpacityOutput.value = this.value;
statesHalo.attr("opacity", this.value);
styleStatesHaloOpacity.addEventListener("input", e => {
statesHalo.attr("opacity", e.target.value);
});
styleStatesHaloBlur.addEventListener("input", function () {
styleStatesHaloBlurOutput.value = this.value;
const blur = +this.value > 0 ? `blur(${this.value}px)` : null;
styleStatesHaloBlur.addEventListener("input", e => {
const value = Number(e.target.value);
const blur = value > 0 ? `blur(${value}px)` : null;
statesHalo.attr("filter", blur);
});
styleArmiesFillOpacity.addEventListener("input", function () {
armies.attr("fill-opacity", this.value);
styleArmiesFillOpacityOutput.value = this.value;
styleArmiesFillOpacity.addEventListener("input", e => {
armies.attr("fill-opacity", e.target.value);
});
styleArmiesSize.addEventListener("input", function () {
armies.attr("box-size", this.value).attr("font-size", this.value * 2);
styleArmiesSizeOutput.value = this.value;
styleArmiesSize.addEventListener("input", e => {
const value = Number(e.target.value);
armies.attr("box-size", value).attr("font-size", value * 2);
armies.selectAll("g").remove(); // clear armies layer
pack.states.forEach(s => {
if (!s.i || s.removed || !s.military.length) return;
@ -1029,7 +1013,7 @@ styleVignettePreset.addEventListener("change", function () {
const vignette = byId("vignette");
if (vignette) {
styleOpacityInput.value = styleOpacityOutput.value = vignette.getAttribute("opacity");
styleOpacityInput.value = vignette.getAttribute("opacity");
styleFillInput.value = styleFillOutput.value = vignette.getAttribute("fill");
styleFilterInput.value = vignette.getAttribute("filter");
}
@ -1043,37 +1027,36 @@ styleVignettePreset.addEventListener("change", function () {
styleVignetteHeight.value = digit(maskRect.getAttribute("height"));
styleVignetteRx.value = digit(maskRect.getAttribute("rx"));
styleVignetteRy.value = digit(maskRect.getAttribute("ry"));
styleVignetteBlur.value = styleVignetteBlurOutput.value = digit(maskRect.getAttribute("filter"));
styleVignetteBlur.value = digit(maskRect.getAttribute("filter"));
}
});
styleVignetteX.addEventListener("input", function () {
byId("vignette-rect")?.setAttribute("x", `${this.value}%`);
styleVignetteX.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("x", `${e.target.value}%`);
});
styleVignetteWidth.addEventListener("input", function () {
byId("vignette-rect")?.setAttribute("width", `${this.value}%`);
styleVignetteWidth.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("width", `${e.target.value}%`);
});
styleVignetteY.addEventListener("input", function () {
byId("vignette-rect")?.setAttribute("y", `${this.value}%`);
styleVignetteY.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("y", `${e.target.value}%`);
});
styleVignetteHeight.addEventListener("input", function () {
byId("vignette-rect")?.setAttribute("height", `${this.value}%`);
styleVignetteHeight.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("height", `${e.target.value}%`);
});
styleVignetteRx.addEventListener("input", function () {
byId("vignette-rect")?.setAttribute("rx", `${this.value}%`);
styleVignetteRx.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("rx", `${e.target.value}%`);
});
styleVignetteRy.addEventListener("input", function () {
byId("vignette-rect")?.setAttribute("ry", `${this.value}%`);
styleVignetteRy.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("ry", `${e.target.value}%`);
});
styleVignetteBlur.addEventListener("input", function () {
styleVignetteBlurOutput.value = this.value;
byId("vignette-rect")?.setAttribute("filter", `blur(${this.value}px)`);
styleVignetteBlur.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("filter", `blur(${e.target.value}px)`);
});
styleScaleBar.addEventListener("input", function (event) {
@ -1087,9 +1070,9 @@ styleScaleBar.addEventListener("input", function (event) {
else if (id === "styleScaleBarPositionX") scaleBar.attr("data-x", value);
else if (id === "styleScaleBarPositionY") scaleBar.attr("data-y", value);
else if (id === "styleScaleBarLabel") scaleBar.attr("data-label", value);
else if (id === "styleScaleBarBackgroundOpacityInput") scaleBarBack.attr("opacity", value);
else if (id === "styleScaleBarBackgroundFillInput") scaleBarBack.attr("fill", value);
else if (id === "styleScaleBarBackgroundStrokeInput") scaleBarBack.attr("stroke", value);
else if (id === "styleScaleBarBackgroundOpacity") scaleBarBack.attr("opacity", value);
else if (id === "styleScaleBarBackgroundFill") scaleBarBack.attr("fill", value);
else if (id === "styleScaleBarBackgroundStroke") scaleBarBack.attr("stroke", value);
else if (id === "styleScaleBarBackgroundStrokeWidth") scaleBarBack.attr("stroke-width", value);
else if (id === "styleScaleBarBackgroundFilter") scaleBarBack.attr("filter", value);
else if (id === "styleScaleBarBackgroundPaddingTop") scaleBarBack.attr("data-top", value);

View file

@ -77,7 +77,7 @@ toolsContent.addEventListener("click", function (event) {
function processFeatureRegeneration(event, button) {
if (button === "regenerateStateLabels") drawStateLabels();
else if (button === "regenerateReliefIcons") {
ReliefIcons();
ReliefIcons.draw();
if (!layerIsOn("toggleRelief")) toggleRelief();
} else if (button === "regenerateRoutes") {
regenerateRoutes();
@ -176,7 +176,7 @@ function recreateStates() {
const localSeed = generateSeed();
Math.random = aleaPRNG(localSeed);
const statesCount = +regionsOutput.value;
const statesCount = +byId("").value;
if (!statesCount) {
tip(`<i>States Number</i> option value is zero. No counties are generated`, false, "error");
return null;
@ -198,7 +198,7 @@ function recreateStates() {
const lockedStatesIds = lockedStates.map(s => s.i);
const lockedStatesCapitals = lockedStates.map(s => s.capital);
if (lockedStates.length === validStates.length) {
if (validStates.length && lockedStates.length === validStates.length) {
tip("Unable to regenerate as all states are locked", false, "error");
return null;
}
@ -317,7 +317,7 @@ function recreateStates() {
: pack.cultures[culture].type === "Nomadic"
? "Generic"
: pack.cultures[culture].type;
const expansionism = rn(Math.random() * powerInput.value + 1, 1);
const expansionism = rn(Math.random() * byId("sizeVariety").value + 1, 1);
const cultureType = pack.cultures[culture].type;
const coa = COA.generate(capital.coa, 0.3, null, cultureType);

View file

@ -22,7 +22,14 @@ function each(n) {
return i => i % n === 0;
}
// random number (normal or gaussian distribution)
/* Random Gaussian number generator
* @param {number} expected - expected value
* @param {number} deviation - standard deviation
* @param {number} min - minimum value
* @param {number} max - maximum value
* @param {number} round - round value to n decimals
* @return {number} random number
*/
function gauss(expected = 100, deviation = 30, min = 0, max = 300, round = 0) {
return rn(minmax(d3.randomNormal(expected, deviation)(), min, max), round);
}