river edit: allow to add interim points

This commit is contained in:
Azgaar 2021-08-24 22:24:33 +03:00
parent c1533c5408
commit 008aea2b2f
3 changed files with 58 additions and 39 deletions

View file

@ -985,16 +985,16 @@ body button.noicon {
#controlPoints > path { #controlPoints > path {
fill: none; fill: none;
stroke: #000000; stroke: #0a0909;
stroke-width: 2; stroke-width: 2;
opacity: 0.4; opacity: 0.4;
cursor: pointer; cursor: pointer;
} }
#controlCells > .current { #controlCells {
fill: #82c8ff40; pointer-events: none;
stroke: #82c8ff; fill: #82c8ff80;
stroke-width: 0.4; stroke: "none";
} }
#vertices > circle { #vertices > circle {

View file

@ -319,9 +319,10 @@ window.Rivers = (function () {
}; };
const getRiverPoints = (riverCells, riverPoints) => { const getRiverPoints = (riverCells, riverPoints) => {
if (riverPoints) return riverPoints;
const {p} = pack.cells; const {p} = pack.cells;
return riverCells.map((cell, i) => { return riverCells.map((cell, i) => {
if (riverPoints && riverPoints[i]) return riverPoints[i];
if (cell === -1) return getBorderPoint(riverCells[i - 1]); if (cell === -1) return getBorderPoint(riverCells[i - 1]);
return p[cell]; return p[cell];
}); });

View file

@ -8,9 +8,9 @@ function editRiver(id) {
document.getElementById("toggleCells").dataset.forced = +!layerIsOn("toggleCells"); document.getElementById("toggleCells").dataset.forced = +!layerIsOn("toggleCells");
if (!layerIsOn("toggleCells")) toggleCells(); if (!layerIsOn("toggleCells")) toggleCells();
elSelected = d3.select("#" + id); elSelected = d3.select("#" + id).on("click", addControlPoint);
tip("Drag control points to change the river course. For major changes please create a new river instead", true); tip("Drag control points to change the river course. Click on point to remove it. Click on river to add additional control point. 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");
@ -19,8 +19,8 @@ function editRiver(id) {
const river = getRiver(); const river = getRiver();
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);
drawCells(cells, "current"); drawCells(cells);
$("#riverEditor").dialog({ $("#riverEditor").dialog({
title: "Edit River", title: "Edit River",
@ -92,37 +92,35 @@ function editRiver(id) {
document.getElementById("riverWidth").value = width; document.getElementById("riverWidth").value = width;
} }
function drawControlPoints(points, cells) { function drawControlPoints(points) {
debug debug
.select("#controlPoints") .select("#controlPoints")
.selectAll("circle") .selectAll("circle")
.data(points) .data(points)
.enter() .join("circle")
.append("circle")
.attr("cx", d => d[0]) .attr("cx", d => d[0])
.attr("cy", d => d[1]) .attr("cy", d => d[1])
.attr("r", 0.6) .attr("r", 0.6)
.attr("data-cell", (d, i) => cells[i]) .call(d3.drag().on("start", dragControlPoint))
.attr("data-i", (d, i) => i) .on("click", removeControlPoint);
.call(d3.drag().on("start", dragControlPoint));
} }
function drawCells(cells, type) { function drawCells(cells) {
const validCells = [...new Set(cells)].filter(i => pack.cells.i[i]);
debug debug
.select("#controlCells") .select("#controlCells")
.selectAll(`polygon.${type}`) .selectAll(`polygon`)
.data(cells.filter(i => pack.cells.i[i])) .data(validCells)
.join("polygon") .join("polygon")
.attr("points", d => getPackPolygon(d)) .attr("points", d => getPackPolygon(d));
.attr("class", type);
} }
function dragControlPoint() { function dragControlPoint() {
const {i, r, fl} = pack.cells; const {r, fl} = pack.cells;
const river = getRiver(); const river = getRiver();
const initCell = +this.dataset.cell; const {x: x0, y: y0} = d3.event;
const index = +this.dataset.i; const initCell = findCell(x0, y0);
let movedToCell = null; let movedToCell = null;
@ -136,22 +134,17 @@ function editRiver(id) {
this.setAttribute("cy", y); this.setAttribute("cy", y);
this.__data__ = [rn(x, 1), rn(y, 1)]; this.__data__ = [rn(x, 1), rn(y, 1)];
redrawRiver(); redrawRiver();
drawCells(river.cells);
}); });
d3.event.on("end", () => { d3.event.on("end", () => {
if (movedToCell) { if (movedToCell && !r[movedToCell]) {
this.dataset.cell = movedToCell; // swap river data
river.cells[index] = movedToCell; r[initCell] = 0;
drawCells(river.cells, "current"); r[movedToCell] = river.i;
const sourceFlux = fl[initCell];
if (!r[movedToCell]) { fl[initCell] = fl[movedToCell];
// swap river data fl[movedToCell] = sourceFlux;
r[initCell] = 0;
r[movedToCell] = river.i;
const sourceFlux = fl[initCell];
fl[initCell] = fl[movedToCell];
fl[movedToCell] = sourceFlux;
}
} }
}); });
} }
@ -159,8 +152,10 @@ function editRiver(id) {
function redrawRiver() { function redrawRiver() {
const river = getRiver(); const river = getRiver();
river.points = debug.selectAll("#controlPoints > *").data(); river.points = debug.selectAll("#controlPoints > *").data();
const {cells, widthFactor, sourceWidth} = river; river.cells = river.points.map(([x, y]) => findCell(x, y));
const meanderedPoints = Rivers.addMeandering(cells, river.points);
const {widthFactor, sourceWidth} = river;
const meanderedPoints = Rivers.addMeandering(river.cells, river.points);
lineGen.curve(d3.curveCatmullRom.alpha(0.1)); lineGen.curve(d3.curveCatmullRom.alpha(0.1));
const path = Rivers.getRiverPath(meanderedPoints, widthFactor, sourceWidth); const path = Rivers.getRiverPath(meanderedPoints, widthFactor, sourceWidth);
@ -170,6 +165,27 @@ function editRiver(id) {
if (modules.elevation) showEPForRiver(elSelected.node()); if (modules.elevation) showEPForRiver(elSelected.node());
} }
function addControlPoint() {
const [x, y] = d3.mouse(this);
const point = [rn(x, 1), rn(y, 1)];
const river = getRiver();
if (!river.points) river.points = debug.selectAll("#controlPoints > *").data();
const index = getSegmentId(river.points, point, 2);
river.points.splice(index, 0, point);
drawControlPoints(river.points);
redrawRiver();
}
function removeControlPoint() {
this.remove();
redrawRiver();
const {cells} = getRiver();
drawCells(cells);
}
function changeName() { function changeName() {
getRiver().name = this.value; getRiver().name = this.value;
} }
@ -244,6 +260,8 @@ function editRiver(id) {
function closeRiverEditor() { function closeRiverEditor() {
debug.select("#controlPoints").remove(); debug.select("#controlPoints").remove();
debug.select("#controlCells").remove(); debug.select("#controlCells").remove();
elSelected.on("click", null);
unselect(); unselect();
clearMainTip(); clearMainTip();