diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b254d0ad..acedeb18 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -14,8 +14,8 @@ # Versioning - diff --git a/LICENSE b/LICENSE index 45f950ac..4b0e677e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ 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 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 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 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -21,4 +22,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/components/slider-input.js b/components/slider-input.js new file mode 100644 index 00000000..f1732027 --- /dev/null +++ b/components/slider-input.js @@ -0,0 +1,78 @@ +{ + 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 */ ` + + + `; + + class SliderInput extends HTMLElement { + constructor() { + super(); + this.appendChild(template.content.cloneNode(true)); + + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + + range.value = number.value = this.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 value = e.target.value; + const isNaN = Number.isNaN(Number(value)); + if (isNaN || value === "") return e.stopPropagation(); + + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + this.value = range.value = number.value = value; + + this.dispatchEvent( + new CustomEvent(e.type, { + detail: {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); +} diff --git a/icons.css b/icons.css index ae40ee00..4740f091 100644 --- a/icons.css +++ b/icons.css @@ -253,7 +253,7 @@ .icon-coa:before {content:'\f3ed'; font-size: .9em; color: #999;} /* '' */ .icon-half:before {font-weight: bold;content:'½';} .icon-voice:before {content:'🔊';} - +.icon-robot:before {content:'🤖';} .icon-die:before {content:'🎲';} .icon-button-die:before {content:'🎲'; padding-right: .4em;} .icon-button-power:before {content:'💪'; padding-right: .6em;} diff --git a/index.css b/index.css index d5c5ef34..eb1e82fc 100644 --- a/index.css +++ b/index.css @@ -258,7 +258,6 @@ i.icon-lock { cursor: pointer; } -#routeEditor > *, #labelEditor div { display: inline-block; } @@ -357,6 +356,14 @@ text.drag { font-weight: bold; } +button.ui-button:disabled { + filter: brightness(0.95); +} + +button.ui-button:disabled:hover { + cursor: default; +} + .ui-dialog, #optionsContainer { user-select: none; @@ -437,6 +444,14 @@ button.options:hover { 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 { text-align: justify; } @@ -518,7 +533,53 @@ 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"] { + appearance: textfield; + -moz-appearance: textfield; +} + +#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; @@ -561,55 +622,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%; } @@ -634,19 +647,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; } @@ -717,9 +717,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; @@ -734,7 +731,7 @@ input[type="color"]::-webkit-color-swatch-wrapper { background-color: var(--header-active); } -#toolsContent div { +#toolsContent > .grid { display: grid; grid-template-columns: repeat(4, 1fr); margin: 0.2em 0; @@ -758,7 +755,7 @@ input[type="color"]::-webkit-color-swatch-wrapper { #viewMode > button { padding: 0.35em; - margin: 0.2em 0.3em 0.6em 0.3em; + margin: 0.3em 0.3em 0.6em 0.3em; float: left; width: 30.7%; } @@ -1261,7 +1258,6 @@ i.resetButton:active { padding: 0; height: 2px; background: #d4d4d4; - top: -0.35em; position: relative; appearance: none; -webkit-appearance: none; @@ -1610,6 +1606,7 @@ div.states > .riverType { #burgBody > div > div, #riverBody > div, +#routeBody > div, #lakeBody > div { padding: 0.1em; } @@ -1617,6 +1614,7 @@ div.states > .riverType { #riverBody div.label, #riverBody input, #riverBody select, +#routeBody div.label, #lakeBody div.label, #lakeBody input, #lakeBody select { @@ -1624,6 +1622,12 @@ div.states > .riverType { width: 7em; } +#routeBody input, +#routeBody select { + display: inline-block; + width: 10em; +} + #stateNameEditor div.label, #provinceNameEditor div.label, #regimentBody div.label, @@ -1829,11 +1833,6 @@ div.editorLine { padding: 0px 3px !important; } -#unitsBody > div > * { - display: inline-block; - margin-bottom: 0.2em; -} - .unitsHeader { margin: 0.8em 0 0 -1.1em; font-weight: bold; @@ -1845,28 +1844,21 @@ div.editorLine { margin: 6px 0 0 6px; } -#unitsBody > div > div { +#unitsBody label { + display: inline-block; width: 9em; } -#unitsBody > div > input[type="range"] { - width: 7em; -} - #unitsBody > div > select, #unitsBody > div > input[type="text"] { - width: 12em; -} - -#unitsBody > div > input[type="number"] { - width: 4.35em; -} - -#unitsBody > div > input, -#unitsBody > div > select { + width: 14.4em; border: 1px solid #e9e9e9; } +#unitsBody input[type="range"] { + width: 9em; +} + #unitsEditor i.icon-lock-open, #unitsEditor i.icon-lock { color: #626573; @@ -2181,7 +2173,7 @@ svg.button { #worldControls input[type="number"] { border: 1px solid #e5e5e5; padding: 0px; - width: 3.2em; + width: 4em; } #worldControls i.icon-lock-open, @@ -2240,10 +2232,6 @@ svg.button { fill: blue; } -#globeOutline { - fill: url(#temperatureGradient); -} - #globeArea { fill: white; fill-opacity: 0.3; @@ -2254,6 +2242,11 @@ svg.button { stroke-width: 0.2; } +#globePrimeMeridian { + stroke: blue; + stroke-width: 1.4; +} + #globeEquator { stroke: red; stroke-width: 1.4; @@ -2375,6 +2368,38 @@ svg.button { 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; +} + +@keyframes clockwiseBorderPulse { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + @media print { div, canvas { diff --git a/index.html b/index.html index 384bafc8..42bc9c5f 100644 --- a/index.html +++ b/index.html @@ -138,7 +138,7 @@ } - + @@ -380,7 +380,7 @@ - +
Azgaar's
@@ -469,9 +469,7 @@ onclick="removePreset()" > -

- Displayed layers and layers order: -

+

Displayed layers and layers order:

+
Click to toggle, drag to raise or lower the layer
+
Ctrl + click to edit layer style

View mode:

@@ -835,27 +836,24 @@ - + Terracing - - 0 + Reduce layers - - 5 + Simplify line - - 0 + @@ -873,7 +871,7 @@ Color scheme - + @@ -1240,7 +1240,7 @@ - + @@ -1280,16 +1280,14 @@ Fill opacity - - 0.3 + Labels size - - 8 + @@ -1306,8 +1304,7 @@ Body opacity - - + @@ -1316,27 +1313,30 @@ - 10 + Halo opacity - - 1 + Halo blur - - 4 + @@ -1345,62 +1345,36 @@ Fill opacity - - 1 + Box Size - - 3 + - State Size + State size - + - Province Size + Province size - + - Burg Size + Burg size - + @@ -1488,15 +1462,14 @@ Back opacity - - + Back fill - + @@ -1504,7 +1477,7 @@ Back stroke - + Width @@ -1566,7 +1539,9 @@ - + - + + + Points number - + 10K @@ -1622,7 +1607,7 @@ - + Year and era @@ -1695,53 +1680,41 @@ - + States number - - - - - + + - + Provinces ratio - - - - - + + - + Size variety - - - - - + + - + Growth rate - - - - - + + @@ -1762,14 +1735,17 @@ data-tip="Define how many organized religions and cults should be generated. Cultures will have their own folk religions in any case" > - + Religions number - - - - - + + @@ -1798,22 +1774,16 @@ > Interface size - - - - - + + Tooltip size - - - - - + + @@ -1833,11 +1803,8 @@ Transparency - - - - - + + @@ -2052,23 +2019,16 @@
-

Click to configure:

-
- +
Edit
+
- - - - - - - - -
- -

Click to overview:

-
- - - - + + + + + + +
-

Click to regenerate:

-
+
Regenerate
+
+ + + + - - - - - - - - - +
-

Click to add:

-
+
Add
+
- - + +
-

Click to create a new map:

-
+
Show
+
+ + +
+ +
Create
+
@@ -2307,8 +2277,7 @@

- Fantasy Map Generator is a - free + Fantasy Map Generator is an open source @@ -2327,7 +2296,7 @@

Join our Discord server and Reddit community 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.

@@ -2525,15 +2494,15 @@

-
-
+ +
+
+ +
+ Presets: + + + + +
+ + + @@ -2804,7 +2829,7 @@
Type:
- + @@ -3422,10 +3494,10 @@ - +
@@ -3451,7 +3523,8 @@ - + + - + @@ -4595,26 +4604,10 @@ @@ -4894,7 +4887,11 @@
- + @@ -4954,6 +4942,7 @@
+
+ +
@@ -5398,6 +5356,47 @@
+ +