mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
refactor dialogs to be mobile-friendly
This commit is contained in:
parent
8b1778cb93
commit
8a9a29a9d3
16 changed files with 402 additions and 373 deletions
|
|
@ -16,7 +16,6 @@ export function open() {
|
|||
$("#culturesEditor").dialog({
|
||||
title: "Cultures Editor",
|
||||
resizable: false,
|
||||
width: fitContent(),
|
||||
close: closeCulturesEditor,
|
||||
position: {my: "right top", at: "right-10 top+10", of: "svg"}
|
||||
});
|
||||
|
|
@ -25,15 +24,15 @@ export function open() {
|
|||
|
||||
function insertEditorHtml() {
|
||||
const editorHtml = /* html */ `<div id="culturesEditor" class="dialog stable">
|
||||
<div id="culturesHeader" class="header">
|
||||
<div style="left: 1.8em" data-tip="Click to sort by culture name" class="sortable alphabetically" data-sortby="name">Culture </div>
|
||||
<div style="left: 9.9em" data-tip="Click to sort by type" class="sortable alphabetically" data-sortby="type">Type </div>
|
||||
<div style="left: 16.2em" data-tip="Click to sort by culture namesbase" class="sortable" data-sortby="base">Namesbase </div>
|
||||
<div style="left: 24.5em" data-tip="Click to sort by culture cells count" class="sortable hide" data-sortby="cells">Cells </div>
|
||||
<div style="left: 29.8em" data-tip="Click to sort by expansionism" class="sortable hide" data-sortby="expansionism">Expansion </div>
|
||||
<div style="left: 37.2em" data-tip="Click to sort by culture area" class="sortable hide" data-sortby="area">Area </div>
|
||||
<div style="left: 42.8em" data-tip="Click to sort by culture population" class="sortable hide icon-sort-number-down" data-sortby="population">Population </div>
|
||||
<div style="left: 50.8em" data-tip="Click to sort by culture emblems shape" class="sortable alphabetically hide" data-sortby="emblems">Emblems </div>
|
||||
<div id="culturesHeader" class="header" style="grid-template-columns: 10em 7em 8em 4em 8em 5em 8em 8em">
|
||||
<div data-tip="Click to sort by culture name" class="sortable alphabetically" data-sortby="name">Culture </div>
|
||||
<div data-tip="Click to sort by type" class="sortable alphabetically" data-sortby="type">Type </div>
|
||||
<div data-tip="Click to sort by culture namesbase" class="sortable" data-sortby="base">Namesbase </div>
|
||||
<div data-tip="Click to sort by culture cells count" class="sortable hide" data-sortby="cells">Cells </div>
|
||||
<div data-tip="Click to sort by expansionism" class="sortable hide" data-sortby="expansionism">Expansion </div>
|
||||
<div data-tip="Click to sort by culture area" class="sortable hide" data-sortby="area">Area </div>
|
||||
<div data-tip="Click to sort by culture population" class="sortable hide icon-sort-number-down" data-sortby="population">Population </div>
|
||||
<div data-tip="Click to sort by culture emblems shape" class="sortable alphabetically hide" data-sortby="emblems">Emblems </div>
|
||||
</div>
|
||||
<div id="culturesBody" class="table" data-type="absolute"></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ export function open() {
|
|||
$("#statesEditor").dialog({
|
||||
title: "States Editor",
|
||||
resizable: false,
|
||||
width: fitContent(),
|
||||
close: closeStatesEditor,
|
||||
position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
|
||||
});
|
||||
|
|
@ -22,17 +21,17 @@ export function open() {
|
|||
|
||||
function insertEditorHtml() {
|
||||
const editorHtml = /* html */ `<div id="statesEditor" class="dialog stable">
|
||||
<div id="statesHeader" class="header">
|
||||
<div style="left: 1.8em" data-tip="Click to sort by state name" class="sortable alphabetically" data-sortby="name">State </div>
|
||||
<div style="left: 10.8em" data-tip="Click to sort by state form name" class="sortable alphabetically" data-sortby="form">Form </div>
|
||||
<div style="left: 19.1em" data-tip="Click to sort by capital name" class="sortable alphabetically hide" data-sortby="capital">Capital </div>
|
||||
<div style="left: 26.1em" data-tip="Click to sort by state dominant culture" class="sortable alphabetically hide" data-sortby="culture">Culture </div>
|
||||
<div style="left: 33.4em" data-tip="Click to sort by state burgs count" class="sortable hide" data-sortby="burgs">Burgs </div>
|
||||
<div style="left: 39.6em" data-tip="Click to sort by state area" class="sortable hide icon-sort-number-down" data-sortby="area">Area </div>
|
||||
<div style="left: 45.9em" data-tip="Click to sort by state population" class="sortable hide" data-sortby="population">Population </div>
|
||||
<div style="left: 52.2em" data-tip="Click to sort by state type" class="sortable alphabetically hidden show hide" data-sortby="type">Type </div>
|
||||
<div style="left: 59em" data-tip="Click to sort by state expansion value" class="sortable hidden show hide" data-sortby="expansionism">Expansion </div>
|
||||
<div style="left: 65.5em" data-tip="Click to sort by state cells count" class="sortable hidden show hide" data-sortby="cells">Cells </div>
|
||||
<div id="statesHeader" class="header" style="grid-template-columns: 11em 8em 7em 7em 6em 6em 8em 6em 7em 6em">
|
||||
<div data-tip="Click to sort by state name" class="sortable alphabetically" data-sortby="name">State </div>
|
||||
<div data-tip="Click to sort by state form name" class="sortable alphabetically" data-sortby="form">Form </div>
|
||||
<div data-tip="Click to sort by capital name" class="sortable alphabetically hide" data-sortby="capital">Capital </div>
|
||||
<div data-tip="Click to sort by state dominant culture" class="sortable alphabetically hide" data-sortby="culture">Culture </div>
|
||||
<div data-tip="Click to sort by state burgs count" class="sortable hide" data-sortby="burgs">Burgs </div>
|
||||
<div data-tip="Click to sort by state area" class="sortable hide icon-sort-number-down" data-sortby="area">Area </div>
|
||||
<div data-tip="Click to sort by state population" class="sortable hide" data-sortby="population">Population </div>
|
||||
<div data-tip="Click to sort by state type" class="sortable alphabetically hidden show hide" data-sortby="type">Type </div>
|
||||
<div data-tip="Click to sort by state expansion value" class="sortable hidden show hide" data-sortby="expansionism">Expansion </div>
|
||||
<div data-tip="Click to sort by state cells count" class="sortable hidden show hide" data-sortby="cells">Cells </div>
|
||||
</div>
|
||||
|
||||
<div id="statesBodySection" class="table" data-type="absolute"></div>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ const heightmaps = [
|
|||
{id: "world-from-pacific", name: "World from Pacific"}
|
||||
];
|
||||
|
||||
const initialSeed = generateSeed();
|
||||
appendStyleSheet();
|
||||
insertEditorHtml();
|
||||
addListeners();
|
||||
|
|
@ -107,6 +108,14 @@ function appendStyleSheet() {
|
|||
}
|
||||
}
|
||||
|
||||
.heightmap-selection_options {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(50%, 200px));
|
||||
grid-row-gap: 6px;
|
||||
justify-items: start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.heightmap-selection article {
|
||||
padding: 4px;
|
||||
border-radius: 8px;
|
||||
|
|
@ -154,15 +163,49 @@ function appendStyleSheet() {
|
|||
}
|
||||
|
||||
function insertEditorHtml() {
|
||||
const seed = generateSeed();
|
||||
const heightmapSelectionHtml = /* html */ `<div id="heightmapSelection" class="dialog stable">
|
||||
<div class="heightmap-selection">
|
||||
<section>
|
||||
<header><h1>Heightmap templates</h1></header>
|
||||
<div class="heightmap-selection_container"></div>
|
||||
</section>
|
||||
<section>
|
||||
<header><h1>Pre-created heightmaps</h1></header>
|
||||
<div class="heightmap-selection_container"></div>
|
||||
</section>
|
||||
<section>
|
||||
<header><h1>Options</h1></header>
|
||||
<div class="heightmap-selection_options">
|
||||
<div>
|
||||
<input id="heightmapSelectionRenderOcean" class="checkbox" type="checkbox" />
|
||||
<label for="heightmapSelectionRenderOcean" class="checkbox-label">Render ocean heights</label>
|
||||
</div>
|
||||
<div>
|
||||
Color scheme
|
||||
<select id="heightmapSelectionColorScheme">
|
||||
<option value="bright" selected>Bright</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="green">Green</option>
|
||||
<option value="monochrome">Monochrome</option>
|
||||
</select>
|
||||
</div>
|
||||
<button data-tip="Open Template Editor" id="heightmapSelectionEditTemplates">Edit Templates</button>
|
||||
<button data-tip="Open Image Converter" id="heightmapSelectionImportHeightmap">Import Heightmap</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
const templatesHtml = templates
|
||||
byId("dialogs").insertAdjacentHTML("beforeend", heightmapSelectionHtml);
|
||||
const sections = document.getElementsByClassName("heightmap-selection_container");
|
||||
|
||||
sections[0].innerHTML = templates
|
||||
.map(({id, name}) => {
|
||||
Math.random = aleaPRNG(seed);
|
||||
Math.random = aleaPRNG(initialSeed);
|
||||
const heights = generateHeightmap(id);
|
||||
const dataUrl = drawHeights(heights);
|
||||
|
||||
return /* html */ `<article data-id="${id}" data-seed="${seed}">
|
||||
return /* html */ `<article data-id="${id}" data-seed="${initialSeed}">
|
||||
<img src="${dataUrl}" alt="${name}" />
|
||||
<div>
|
||||
${name}
|
||||
|
|
@ -172,35 +215,16 @@ function insertEditorHtml() {
|
|||
})
|
||||
.join("");
|
||||
|
||||
const heightmapsHtml = heightmaps
|
||||
sections[1].innerHTML = heightmaps
|
||||
.map(({id, name}) => {
|
||||
drawPrecreatedHeightmap(id);
|
||||
|
||||
return /* html */ `<article data-id="${id}" data-seed="${seed}">
|
||||
return /* html */ `<article data-id="${id}" data-seed="${initialSeed}">
|
||||
<img alt="${name}" />
|
||||
<div>${name}</div>
|
||||
</article>`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
const heightmapSelectionHtml = /* html */ `<div id="heightmapSelection" class="dialog stable">
|
||||
<div class="heightmap-selection">
|
||||
<section>
|
||||
<header><h1>Heightmap templates</h1></header>
|
||||
<div class="heightmap-selection_container">
|
||||
${templatesHtml}
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<header><h1>Pre-created heightmaps</h1></header>
|
||||
<div class="heightmap-selection_container">
|
||||
${heightmapsHtml}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
byId("dialogs").insertAdjacentHTML("beforeend", heightmapSelectionHtml);
|
||||
}
|
||||
|
||||
function addListeners() {
|
||||
|
|
@ -209,9 +233,16 @@ function addListeners() {
|
|||
if (!article) return;
|
||||
|
||||
const id = article.dataset.id;
|
||||
if (event.target.matches("span.icon-cw")) regeneratePreview(article, id);
|
||||
else setSelected(id);
|
||||
if (event.target.matches("span.icon-cw")) {
|
||||
const seed = generateSeed();
|
||||
article.dataset.seed = seed;
|
||||
Math.random = aleaPRNG(seed);
|
||||
drawTemplatePreview(id);
|
||||
} else setSelected(id);
|
||||
});
|
||||
|
||||
byId("heightmapSelectionRenderOcean").on("change", redrawAll);
|
||||
byId("heightmapSelectionColorScheme").on("change", redrawAll);
|
||||
}
|
||||
|
||||
function getSelected() {
|
||||
|
|
@ -234,11 +265,14 @@ function drawHeights(heights) {
|
|||
canvas.height = grid.cellsY;
|
||||
const ctx = canvas.getContext("2d");
|
||||
const imageData = ctx.createImageData(grid.cellsX, grid.cellsY);
|
||||
const scheme = getColorScheme();
|
||||
const waterColor = scheme(1);
|
||||
|
||||
const schemeId = byId("heightmapSelectionColorScheme").value;
|
||||
const scheme = getColorScheme(schemeId);
|
||||
const renderOcean = byId("heightmapSelectionRenderOcean").checked;
|
||||
const getHeight = height => (height < 20 ? (renderOcean ? height : 0) : height);
|
||||
|
||||
for (let i = 0; i < heights.length; i++) {
|
||||
const color = heights[i] < 20 ? waterColor : scheme(1 - heights[i] / 100);
|
||||
const color = scheme(1 - getHeight(heights[i]) / 100);
|
||||
const {r, g, b} = d3.color(color);
|
||||
|
||||
const n = i * 4;
|
||||
|
|
@ -259,6 +293,13 @@ function generateHeightmap(id) {
|
|||
return heights;
|
||||
}
|
||||
|
||||
function drawTemplatePreview(id) {
|
||||
const heights = generateHeightmap(id);
|
||||
const dataUrl = drawHeights(heights);
|
||||
const article = byId("heightmapSelection").querySelector(`[data-id="${id}"]`);
|
||||
article.querySelector("img").src = dataUrl;
|
||||
}
|
||||
|
||||
async function drawPrecreatedHeightmap(id) {
|
||||
const heights = await HeightmapGenerator.fromPrecreated(id);
|
||||
const dataUrl = drawHeights(heights);
|
||||
|
|
@ -266,12 +307,14 @@ async function drawPrecreatedHeightmap(id) {
|
|||
article.querySelector("img").src = dataUrl;
|
||||
}
|
||||
|
||||
function regeneratePreview(article, id) {
|
||||
const seed = generateSeed();
|
||||
article.dataset.seed = seed;
|
||||
Math.random = aleaPRNG(seed);
|
||||
function redrawAll() {
|
||||
const articles = byId("heightmapSelection").querySelectorAll(`article`);
|
||||
for (const article of articles) {
|
||||
const {id, seed} = article.dataset;
|
||||
Math.random = aleaPRNG(seed);
|
||||
|
||||
const heights = generateHeightmap(id);
|
||||
const dataUrl = drawHeights(heights);
|
||||
article.querySelector("img").src = dataUrl;
|
||||
const isTemplate = id in HeightmapTemplates;
|
||||
if (isTemplate) drawTemplatePreview(id);
|
||||
else drawPrecreatedHeightmap(id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue