mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
heightmap select - open edit tools
This commit is contained in:
parent
8a9a29a9d3
commit
f3a755976a
2 changed files with 93 additions and 58 deletions
|
|
@ -83,7 +83,7 @@ export function open() {
|
||||||
|
|
||||||
function appendStyleSheet() {
|
function appendStyleSheet() {
|
||||||
const styles = /* css */ `
|
const styles = /* css */ `
|
||||||
.heightmap-selection {
|
div.dialog > div.heightmap-selection {
|
||||||
width: 70vw;
|
width: 70vw;
|
||||||
height: 70vh;
|
height: 70vh;
|
||||||
}
|
}
|
||||||
|
|
@ -110,9 +110,13 @@ function appendStyleSheet() {
|
||||||
|
|
||||||
.heightmap-selection_options {
|
.heightmap-selection_options {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(50%, 200px));
|
grid-template-columns: 2fr 1fr;
|
||||||
grid-row-gap: 6px;
|
|
||||||
justify-items: start;
|
justify-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heightmap-selection_options > div:first-child {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,6 +180,7 @@ function insertEditorHtml() {
|
||||||
<section>
|
<section>
|
||||||
<header><h1>Options</h1></header>
|
<header><h1>Options</h1></header>
|
||||||
<div class="heightmap-selection_options">
|
<div class="heightmap-selection_options">
|
||||||
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<input id="heightmapSelectionRenderOcean" class="checkbox" type="checkbox" />
|
<input id="heightmapSelectionRenderOcean" class="checkbox" type="checkbox" />
|
||||||
<label for="heightmapSelectionRenderOcean" class="checkbox-label">Render ocean heights</label>
|
<label for="heightmapSelectionRenderOcean" class="checkbox-label">Render ocean heights</label>
|
||||||
|
|
@ -189,8 +194,12 @@ function insertEditorHtml() {
|
||||||
<option value="monochrome">Monochrome</option>
|
<option value="monochrome">Monochrome</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<button data-tip="Open Template Editor" id="heightmapSelectionEditTemplates">Edit Templates</button>
|
</div>
|
||||||
<button data-tip="Open Image Converter" id="heightmapSelectionImportHeightmap">Import Heightmap</button>
|
<div>
|
||||||
|
<button data-tip="Rerender all preview images" id="heightmapSelectionRedrawPreview">Redraw preview</button>
|
||||||
|
<button data-tip="Open Template Editor" data-tool="templateEditor" id="heightmapSelectionEditTemplates">Edit Templates</button>
|
||||||
|
<button data-tip="Open Image Converter" data-tool="imageConverter" id="heightmapSelectionImportHeightmap">Import Heightmap</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -243,6 +252,9 @@ function addListeners() {
|
||||||
|
|
||||||
byId("heightmapSelectionRenderOcean").on("change", redrawAll);
|
byId("heightmapSelectionRenderOcean").on("change", redrawAll);
|
||||||
byId("heightmapSelectionColorScheme").on("change", redrawAll);
|
byId("heightmapSelectionColorScheme").on("change", redrawAll);
|
||||||
|
byId("heightmapSelectionRedrawPreview").on("click", redrawAll);
|
||||||
|
byId("heightmapSelectionEditTemplates").on("click", confirmHeightmapEdit);
|
||||||
|
byId("heightmapSelectionImportHeightmap").on("click", confirmHeightmapEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelected() {
|
function getSelected() {
|
||||||
|
|
@ -318,3 +330,14 @@ function redrawAll() {
|
||||||
else drawPrecreatedHeightmap(id);
|
else drawPrecreatedHeightmap(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function confirmHeightmapEdit() {
|
||||||
|
const tool = this.dataset.tool;
|
||||||
|
|
||||||
|
confirmationDialog({
|
||||||
|
title: this.dataset.tip,
|
||||||
|
message: "Opening the tool will erase the current map. Are you sure you want to proceed?",
|
||||||
|
confirm: "Continue",
|
||||||
|
onConfirm: () => editHeightmap({mode: "erase", tool})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,13 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function editHeightmap() {
|
function editHeightmap(options) {
|
||||||
void (function selectEditMode() {
|
const {mode, tool} = options || {};
|
||||||
alertMessage.innerHTML = /* html */ `Heightmap is a core element on which all other data (rivers, burgs, states etc) is based. So the best edit approach is to
|
|
||||||
<i>erase</i> the secondary data and let the system automatically regenerate it on edit completion.
|
|
||||||
<p><i>Erase</i> mode also allows you Convert an Image into a heightmap or use Template Editor.</p>
|
|
||||||
<p>You can <i>keep</i> the data, but you won't be able to change the coastline.</p>
|
|
||||||
<p>
|
|
||||||
Try <i>risk</i> mode to change the coastline and keep the data. The data will be restored as much as possible, but it can cause unpredictable errors.
|
|
||||||
</p>
|
|
||||||
<p>Please <span class="pseudoLink" onclick="dowloadMap();" editHeightmap();>save the map</span> before editing the heightmap!</p>
|
|
||||||
<p style="margin-bottom: 0">Check out ${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization", "wiki")} for guidance.</p>`;
|
|
||||||
|
|
||||||
$("#alert").dialog({
|
|
||||||
resizable: false,
|
|
||||||
title: "Edit Heightmap",
|
|
||||||
width: "28em",
|
|
||||||
buttons: {
|
|
||||||
Erase: () => enterHeightmapEditMode("erase"),
|
|
||||||
Keep: () => enterHeightmapEditMode("keep"),
|
|
||||||
Risk: () => enterHeightmapEditMode("risk"),
|
|
||||||
Cancel: function () {
|
|
||||||
$(this).dialog("close");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
restartHistory();
|
restartHistory();
|
||||||
viewbox.insert("g", "#terrs").attr("id", "heights");
|
viewbox.insert("g", "#terrs").attr("id", "heights");
|
||||||
|
|
||||||
|
if (!mode) showModeDialog();
|
||||||
|
else enterHeightmapEditMode(mode);
|
||||||
|
|
||||||
if (modules.editHeightmap) return;
|
if (modules.editHeightmap) return;
|
||||||
modules.editHeightmap = true;
|
modules.editHeightmap = true;
|
||||||
|
|
||||||
|
|
@ -44,35 +22,66 @@ function editHeightmap() {
|
||||||
byId("templateUndo").on("click", () => restoreHistory(edits.n - 1));
|
byId("templateUndo").on("click", () => restoreHistory(edits.n - 1));
|
||||||
byId("templateRedo").on("click", () => restoreHistory(edits.n + 1));
|
byId("templateRedo").on("click", () => restoreHistory(edits.n + 1));
|
||||||
|
|
||||||
function enterHeightmapEditMode(type) {
|
function showModeDialog() {
|
||||||
|
alertMessage.innerHTML = /* html */ `Heightmap is a core element on which all other data (rivers, burgs, states etc) is based. So the best edit approach is to
|
||||||
|
<i>erase</i> the secondary data and let the system automatically regenerate it on edit completion.
|
||||||
|
<p><i>Erase</i> mode also allows you Convert an Image into a heightmap or use Template Editor.</p>
|
||||||
|
<p>You can <i>keep</i> the data, but you won't be able to change the coastline.</p>
|
||||||
|
<p>Try <i>risk</i> mode to change the coastline and keep the data. The data will be restored as much as possible, but it can cause unpredictable errors.</p>
|
||||||
|
<p>Please <span class="pseudoLink" onclick="dowloadMap();">save the map</span> before editing the heightmap!</p>
|
||||||
|
<p style="margin-bottom: 0">Check out ${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization", "wiki")} for guidance.</p>`;
|
||||||
|
|
||||||
|
$("#alert").dialog({
|
||||||
|
resizable: false,
|
||||||
|
title: "Edit Heightmap",
|
||||||
|
width: "28em",
|
||||||
|
buttons: {
|
||||||
|
Erase: () => enterHeightmapEditMode("erase"),
|
||||||
|
Keep: () => enterHeightmapEditMode("keep"),
|
||||||
|
Risk: () => enterHeightmapEditMode("risk"),
|
||||||
|
Cancel: function () {
|
||||||
|
$(this).dialog("close");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function enterHeightmapEditMode(mode) {
|
||||||
editHeightmap.layers = Array.from(mapLayers.querySelectorAll("li:not(.buttonoff)")).map(node => node.id); // store layers preset
|
editHeightmap.layers = Array.from(mapLayers.querySelectorAll("li:not(.buttonoff)")).map(node => node.id); // store layers preset
|
||||||
editHeightmap.layers.forEach(l => byId(l).click()); // turn off all layers
|
editHeightmap.layers.forEach(l => byId(l).click()); // turn off all layers
|
||||||
|
|
||||||
customization = 1;
|
customization = 1;
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
tip('Heightmap edit mode is active. Click on "Exit Customization" to finalize the heightmap', true);
|
tip('Heightmap edit mode is active. Click on "Exit Customization" to finalize the heightmap', true);
|
||||||
customizationMenu.style.display = "block";
|
|
||||||
toolsContent.style.display = "none";
|
|
||||||
heightmapEditMode.innerHTML = type;
|
|
||||||
|
|
||||||
if (type === "erase") {
|
byId("options")
|
||||||
|
.querySelectorAll(".tabcontent")
|
||||||
|
.forEach(tabcontent => {
|
||||||
|
tabcontent.style.display = "none";
|
||||||
|
});
|
||||||
|
byId("options").querySelector(".tab > .active").classList.remove("active");
|
||||||
|
byId("customizationMenu").style.display = "block";
|
||||||
|
byId("toolsTab").classList.add("active");
|
||||||
|
heightmapEditMode.innerHTML = mode;
|
||||||
|
|
||||||
|
if (mode === "erase") {
|
||||||
undraw();
|
undraw();
|
||||||
changeOnlyLand.checked = false;
|
changeOnlyLand.checked = false;
|
||||||
} else if (type === "keep") {
|
} else if (mode === "keep") {
|
||||||
viewbox.selectAll("#landmass, #lakes").style("display", "none");
|
viewbox.selectAll("#landmass, #lakes").style("display", "none");
|
||||||
changeOnlyLand.checked = true;
|
changeOnlyLand.checked = true;
|
||||||
} else if (type === "risk") {
|
} else if (mode === "risk") {
|
||||||
defs.selectAll("#land, #water").selectAll("path").remove();
|
defs.selectAll("#land, #water").selectAll("path").remove();
|
||||||
viewbox.selectAll("#coastline path, #lakes path, #oceanLayers path").remove();
|
viewbox.selectAll("#coastline path, #lakes path, #oceanLayers path").remove();
|
||||||
changeOnlyLand.checked = false;
|
changeOnlyLand.checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show convert and template buttons for Erase mode only
|
// show convert and template buttons for Erase mode only
|
||||||
applyTemplate.style.display = type === "erase" ? "inline-block" : "none";
|
applyTemplate.style.display = mode === "erase" ? "inline-block" : "none";
|
||||||
convertImage.style.display = type === "erase" ? "inline-block" : "none";
|
convertImage.style.display = mode === "erase" ? "inline-block" : "none";
|
||||||
|
|
||||||
// hide erosion checkbox if mode is Keep
|
// hide erosion checkbox if mode is Keep
|
||||||
allowErosionBox.style.display = type === "keep" ? "none" : "inline-block";
|
allowErosionBox.style.display = mode === "keep" ? "none" : "inline-block";
|
||||||
|
|
||||||
// show finalize button
|
// show finalize button
|
||||||
if (!sessionStorage.getItem("noExitButtonAnimation")) {
|
if (!sessionStorage.getItem("noExitButtonAnimation")) {
|
||||||
|
|
@ -95,27 +104,30 @@ function editHeightmap() {
|
||||||
.style("transform", "scale(1)");
|
.style("transform", "scale(1)");
|
||||||
} else exitCustomization.style.display = "block";
|
} else exitCustomization.style.display = "block";
|
||||||
|
|
||||||
openBrushesPanel();
|
|
||||||
turnButtonOn("toggleHeight");
|
turnButtonOn("toggleHeight");
|
||||||
layersPreset.value = "heightmap";
|
layersPreset.value = "heightmap";
|
||||||
layersPreset.disabled = true;
|
layersPreset.disabled = true;
|
||||||
mockHeightmap();
|
mockHeightmap();
|
||||||
viewbox.on("touchmove mousemove", moveCursor);
|
viewbox.on("touchmove mousemove", moveCursor);
|
||||||
|
|
||||||
|
if (tool === "templateEditor") openTemplateEditor();
|
||||||
|
else if (tool === "imageConverter") openImageConverter();
|
||||||
|
else openBrushesPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveCursor() {
|
function moveCursor() {
|
||||||
const p = d3.mouse(this),
|
const [x, y] = d3.mouse(this);
|
||||||
cell = findGridCell(p[0], p[1]);
|
const cell = findGridCell(x, y);
|
||||||
heightmapInfoX.innerHTML = rn(p[0]);
|
heightmapInfoX.innerHTML = rn(x);
|
||||||
heightmapInfoY.innerHTML = rn(p[1]);
|
heightmapInfoY.innerHTML = rn(y);
|
||||||
heightmapInfoCell.innerHTML = cell;
|
heightmapInfoCell.innerHTML = cell;
|
||||||
heightmapInfoHeight.innerHTML = /* html */ `${grid.cells.h[cell]} (${getHeight(grid.cells.h[cell])})`;
|
heightmapInfoHeight.innerHTML = `${grid.cells.h[cell]} (${getHeight(grid.cells.h[cell])})`;
|
||||||
if (tooltip.dataset.main) showMainTip();
|
if (tooltip.dataset.main) showMainTip();
|
||||||
|
|
||||||
// move radius circle if drag mode is active
|
// move radius circle if drag mode is active
|
||||||
const pressed = byId("brushesButtons").querySelector("button.pressed");
|
const pressed = byId("brushesButtons").querySelector("button.pressed");
|
||||||
if (!pressed) return;
|
if (!pressed) return;
|
||||||
moveCircle(p[0], p[1], brushRadius.valueAsNumber, "#333");
|
moveCircle(x, y, brushRadius.valueAsNumber, "#333");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get user-friendly (real-world) height value from map data
|
// get user-friendly (real-world) height value from map data
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue