mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
rivers editor - optimize
This commit is contained in:
parent
a1425bcb54
commit
c5698c5a11
3 changed files with 15 additions and 106 deletions
|
|
@ -991,12 +991,6 @@ body button.noicon {
|
||||||
stroke-width: 0.4;
|
stroke-width: 0.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#controlCells > .available {
|
|
||||||
fill: #82ff9b40;
|
|
||||||
stroke: #82ff9b;
|
|
||||||
stroke-width: 0.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
#controlCells > .occupied {
|
#controlCells > .occupied {
|
||||||
fill: #ff828240;
|
fill: #ff828240;
|
||||||
stroke: #ff8282;
|
stroke: #ff8282;
|
||||||
|
|
|
||||||
|
|
@ -1656,7 +1656,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="riverBottom">
|
<div id="riverBottom">
|
||||||
<button id="riverNew" data-tip="Create new river clicking on map" class="icon-map-pin"></button>
|
|
||||||
<button id="riverEditStyle" data-tip="Edit style for all rivers in Style Editor" class="icon-brush"></button>
|
<button id="riverEditStyle" data-tip="Edit style for all rivers in Style Editor" class="icon-brush"></button>
|
||||||
<button id="riverElevationProfile" data-tip="Show the elevation profile for the river" class="icon-chart-area"></button>
|
<button id="riverElevationProfile" data-tip="Show the elevation profile for the river" class="icon-chart-area"></button>
|
||||||
<button id="riverLegend" data-tip="Edit free text notes (legend) for the river" class="icon-edit"></button>
|
<button id="riverLegend" data-tip="Edit free text notes (legend) for the river" class="icon-edit"></button>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ function editRiver(id) {
|
||||||
|
|
||||||
elSelected = d3.select("#" + id);
|
elSelected = d3.select("#" + id);
|
||||||
|
|
||||||
viewbox.on("touchmove mousemove", showEditorTips);
|
tip("Drag control points to change the river course. For major changes please create a new river instead", true);
|
||||||
debug.append("g").attr("id", "controlCells");
|
debug.append("g").attr("id", "controlCells");
|
||||||
debug.append("g").attr("id", "controlPoints");
|
debug.append("g").attr("id", "controlPoints");
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ function editRiver(id) {
|
||||||
const {cells, points} = river;
|
const {cells, points} = river;
|
||||||
const riverPoints = Rivers.getRiverPoints(cells, points);
|
const riverPoints = Rivers.getRiverPoints(cells, points);
|
||||||
drawControlPoints(riverPoints, cells);
|
drawControlPoints(riverPoints, cells);
|
||||||
drawRiverCells(cells);
|
drawCells(cells, "current");
|
||||||
|
|
||||||
$("#riverEditor").dialog({
|
$("#riverEditor").dialog({
|
||||||
title: "Edit River",
|
title: "Edit River",
|
||||||
|
|
@ -40,17 +40,11 @@ function editRiver(id) {
|
||||||
document.getElementById("riverMainstem").addEventListener("change", changeParent);
|
document.getElementById("riverMainstem").addEventListener("change", changeParent);
|
||||||
document.getElementById("riverSourceWidth").addEventListener("input", changeSourceWidth);
|
document.getElementById("riverSourceWidth").addEventListener("input", changeSourceWidth);
|
||||||
document.getElementById("riverWidthFactor").addEventListener("input", changeWidthFactor);
|
document.getElementById("riverWidthFactor").addEventListener("input", changeWidthFactor);
|
||||||
document.getElementById("riverNew").addEventListener("click", toggleRiverCreationMode);
|
|
||||||
document.getElementById("riverEditStyle").addEventListener("click", () => editStyle("rivers"));
|
document.getElementById("riverEditStyle").addEventListener("click", () => editStyle("rivers"));
|
||||||
document.getElementById("riverElevationProfile").addEventListener("click", showElevationProfile);
|
document.getElementById("riverElevationProfile").addEventListener("click", showElevationProfile);
|
||||||
document.getElementById("riverLegend").addEventListener("click", editRiverLegend);
|
document.getElementById("riverLegend").addEventListener("click", editRiverLegend);
|
||||||
document.getElementById("riverRemove").addEventListener("click", removeRiver);
|
document.getElementById("riverRemove").addEventListener("click", removeRiver);
|
||||||
|
|
||||||
function showEditorTips() {
|
|
||||||
tip("Drag control points for minor change, to change cells add a new river", true);
|
|
||||||
showMainTip();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRiver() {
|
function getRiver() {
|
||||||
const riverId = +elSelected.attr("id").slice(5);
|
const riverId = +elSelected.attr("id").slice(5);
|
||||||
const river = pack.rivers.find(r => r.i === riverId);
|
const river = pack.rivers.find(r => r.i === riverId);
|
||||||
|
|
@ -112,52 +106,34 @@ function editRiver(id) {
|
||||||
.call(d3.drag().on("start", dragControlPoint));
|
.call(d3.drag().on("start", dragControlPoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawRiverCells(cells) {
|
function drawCells(cells, type) {
|
||||||
debug
|
debug
|
||||||
.select("#controlCells")
|
.select("#controlCells")
|
||||||
.selectAll("polygon.current")
|
.selectAll(`polygon.${type}`)
|
||||||
.data(cells)
|
.data(cells)
|
||||||
.join("polygon")
|
.join("polygon")
|
||||||
.attr("points", d => getPackPolygon(d))
|
.attr("points", d => getPackPolygon(d))
|
||||||
.attr("class", "current");
|
.attr("class", type);
|
||||||
}
|
|
||||||
|
|
||||||
function drawAvailableCells(cells) {
|
|
||||||
debug
|
|
||||||
.select("#controlCells")
|
|
||||||
.selectAll("polygon.available")
|
|
||||||
.data(cells)
|
|
||||||
.join("polygon")
|
|
||||||
.attr("points", d => getPackPolygon(d))
|
|
||||||
.attr("class", "available");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragControlPoint() {
|
function dragControlPoint() {
|
||||||
const {c, r, fl, conf} = pack.cells;
|
const {i, r, fl} = pack.cells;
|
||||||
const river = getRiver();
|
const river = getRiver();
|
||||||
const {cells} = river;
|
|
||||||
|
|
||||||
const initCell = +this.dataset.cell;
|
const initCell = +this.dataset.cell;
|
||||||
const index = +this.dataset.i;
|
const index = +this.dataset.i;
|
||||||
const prev = cells[index - 1];
|
|
||||||
const next = cells[index + 1];
|
|
||||||
const availableCells = conf[initCell]
|
|
||||||
? []
|
|
||||||
: c[initCell]
|
|
||||||
.filter(neib => !r[neib])
|
|
||||||
.filter(neib => !prev || c[neib].includes(prev))
|
|
||||||
.filter(neib => !next || c[neib].includes(next));
|
|
||||||
|
|
||||||
|
const occupiedCells = i.filter(i => r[i] && !river.cells.includes(i));
|
||||||
|
drawCells(occupiedCells, "occupied");
|
||||||
let movedToCell = null;
|
let movedToCell = null;
|
||||||
drawAvailableCells(availableCells);
|
|
||||||
|
|
||||||
d3.event.on("drag", function () {
|
d3.event.on("drag", function () {
|
||||||
const {x, y} = d3.event;
|
const {x, y} = d3.event;
|
||||||
const currentCell = findCell(x, y);
|
const currentCell = findCell(x, y);
|
||||||
|
|
||||||
if (initCell !== currentCell) {
|
if (initCell !== currentCell) {
|
||||||
if (availableCells.includes(currentCell)) movedToCell = currentCell;
|
if (occupiedCells.includes(currentCell)) return;
|
||||||
else return;
|
movedToCell = currentCell;
|
||||||
} else movedToCell = null;
|
} else movedToCell = null;
|
||||||
|
|
||||||
this.setAttribute("cx", x);
|
this.setAttribute("cx", x);
|
||||||
|
|
@ -170,16 +146,17 @@ function editRiver(id) {
|
||||||
if (movedToCell) {
|
if (movedToCell) {
|
||||||
this.dataset.cell = movedToCell;
|
this.dataset.cell = movedToCell;
|
||||||
river.cells[index] = movedToCell;
|
river.cells[index] = movedToCell;
|
||||||
|
drawCells(river.cells, "current");
|
||||||
|
|
||||||
|
// swap river data
|
||||||
r[initCell] = 0;
|
r[initCell] = 0;
|
||||||
r[movedToCell] = river.i;
|
r[movedToCell] = river.i;
|
||||||
const sourceFlux = fl[initCell];
|
const sourceFlux = fl[initCell];
|
||||||
fl[initCell] = fl[movedToCell];
|
fl[initCell] = fl[movedToCell];
|
||||||
fl[movedToCell] = sourceFlux;
|
fl[movedToCell] = sourceFlux;
|
||||||
drawRiverCells(river.cells);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug.select("#controlCells").selectAll("polygon.available").remove();
|
debug.select("#controlCells").selectAll("polygon.available, polygon.occupied").remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,66 +224,6 @@ function editRiver(id) {
|
||||||
editNotes(id, river.name + " " + river.type);
|
editNotes(id, river.name + " " + river.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleRiverCreationMode() {
|
|
||||||
if (document.getElementById("riverNew").classList.contains("pressed")) exitRiverCreationMode();
|
|
||||||
else {
|
|
||||||
document.getElementById("riverNew").classList.add("pressed");
|
|
||||||
tip("Click on map to add control points", true, "warn");
|
|
||||||
viewbox.on("click", addPointOnClick).style("cursor", "crosshair");
|
|
||||||
elSelected.on("click", null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addPointOnClick() {
|
|
||||||
if (!elSelected.attr("data-new")) {
|
|
||||||
debug.select("#controlPoints").selectAll("circle").remove();
|
|
||||||
const id = getNextId("river");
|
|
||||||
elSelected = d3.select(elSelected.node().parentNode).append("path").attr("id", id).attr("data-new", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add control point
|
|
||||||
const point = d3.mouse(this);
|
|
||||||
// addControlPoint([point[0], point[1]]);
|
|
||||||
redrawRiver();
|
|
||||||
}
|
|
||||||
|
|
||||||
function exitRiverCreationMode() {
|
|
||||||
riverNew.classList.remove("pressed");
|
|
||||||
clearMainTip();
|
|
||||||
viewbox.on("click", clicked).style("cursor", "default");
|
|
||||||
|
|
||||||
if (!elSelected.attr("data-new")) return; // no need to create a new river
|
|
||||||
elSelected.attr("data-new", null);
|
|
||||||
|
|
||||||
// add a river
|
|
||||||
const r = +elSelected.attr("id").slice(5);
|
|
||||||
const node = elSelected.node();
|
|
||||||
const length = node.getTotalLength() / 2;
|
|
||||||
|
|
||||||
const cells = [];
|
|
||||||
|
|
||||||
const segments = Math.ceil(length / 4);
|
|
||||||
const increment = rn((length / segments) * 1e5);
|
|
||||||
for (let i = increment * segments, c = i; i >= 0; i -= increment, c += increment) {
|
|
||||||
const p = node.getPointAtLength(i / 1e5);
|
|
||||||
const cell = findCell(p.x, p.y);
|
|
||||||
if (!pack.cells.r[cell]) pack.cells.r[cell] = r;
|
|
||||||
cells.push(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
const source = cells[0];
|
|
||||||
const mouth = last(cells);
|
|
||||||
const name = Rivers.getName(mouth);
|
|
||||||
const smallLength = pack.rivers.map(r => r.length || 0).sort((a, b) => a - b)[Math.ceil(pack.rivers.length * 0.15)];
|
|
||||||
const type = length < smallLength ? rw({Creek: 9, River: 3, Brook: 3, Stream: 1}) : "River";
|
|
||||||
|
|
||||||
const discharge = rn(cells.length * 20 * Math.random());
|
|
||||||
const widthFactor = +document.getElementById("riverWidthFactor").value;
|
|
||||||
const sourceWidth = +document.getElementById("riverSourceWidth").value;
|
|
||||||
|
|
||||||
pack.rivers.push({i: r, source, mouth, discharge, length, width: sourceWidth, widthFactor, sourceWidth, parent: 0, name, type, basin: r});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeRiver() {
|
function removeRiver() {
|
||||||
alertMessage.innerHTML = "Are you sure you want to remove the river and all its tributaries";
|
alertMessage.innerHTML = "Are you sure you want to remove the river and all its tributaries";
|
||||||
$("#alert").dialog({
|
$("#alert").dialog({
|
||||||
|
|
@ -318,7 +235,7 @@ function editRiver(id) {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
const river = +elSelected.attr("id").slice(5);
|
const river = +elSelected.attr("id").slice(5);
|
||||||
Rivers.remove(river);
|
Rivers.remove(river);
|
||||||
elSelected.remove(); // keep if river if missed in pack.rivers
|
elSelected.remove();
|
||||||
$("#riverEditor").dialog("close");
|
$("#riverEditor").dialog("close");
|
||||||
},
|
},
|
||||||
Cancel: function () {
|
Cancel: function () {
|
||||||
|
|
@ -329,11 +246,10 @@ function editRiver(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeRiverEditor() {
|
function closeRiverEditor() {
|
||||||
exitRiverCreationMode();
|
|
||||||
elSelected.on("click", null);
|
|
||||||
debug.select("#controlPoints").remove();
|
debug.select("#controlPoints").remove();
|
||||||
debug.select("#controlCells").remove();
|
debug.select("#controlCells").remove();
|
||||||
unselect();
|
unselect();
|
||||||
|
clearMainTip();
|
||||||
|
|
||||||
const forced = +document.getElementById("toggleCells").dataset.forced;
|
const forced = +document.getElementById("toggleCells").dataset.forced;
|
||||||
document.getElementById("toggleCells").dataset.forced = 0;
|
document.getElementById("toggleCells").dataset.forced = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue