mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
ability to remove icons in bulk via button
This commit is contained in:
parent
c65a044aae
commit
d6c18fb6a2
2 changed files with 70 additions and 42 deletions
|
|
@ -1924,7 +1924,7 @@
|
||||||
<button id="reliefCopy" data-tip="Copy selected relief icon" class="icon-clone"></button>
|
<button id="reliefCopy" data-tip="Copy selected relief icon" class="icon-clone"></button>
|
||||||
<button id="reliefMoveFront" data-tip="Move selected relief icon to front" class="icon-level-up"></button>
|
<button id="reliefMoveFront" data-tip="Move selected relief icon to front" class="icon-level-up"></button>
|
||||||
<button id="reliefMoveBack" data-tip="Move selected relief icon back" class="icon-level-down"></button>
|
<button id="reliefMoveBack" data-tip="Move selected relief icon back" class="icon-level-down"></button>
|
||||||
<button id="reliefRemove" data-tip="Remove selected relief icon. Shortcut: Delete" class="icon-trash fastDelete"></button>
|
<button id="reliefRemove" data-tip="Remove selected relief icon or icon type. Shortcut: Delete" class="icon-trash fastDelete"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ function editReliefIcon() {
|
||||||
updateReliefSizeInput();
|
updateReliefSizeInput();
|
||||||
|
|
||||||
$("#reliefEditor").dialog({
|
$("#reliefEditor").dialog({
|
||||||
title: "Edit Relief Icons", resizable: false, width: "27em",
|
title: "Edit Relief Icons",
|
||||||
|
resizable: false,
|
||||||
|
width: "27em",
|
||||||
position: {my: "left top", at: "left+10 top+10", of: "#map"},
|
position: {my: "left top", at: "left+10 top+10", of: "#map"},
|
||||||
close: closeReliefEditor
|
close: closeReliefEditor
|
||||||
});
|
});
|
||||||
|
|
@ -40,26 +42,27 @@ function editReliefIcon() {
|
||||||
const dx = +this.getAttribute("x") - d3.event.x;
|
const dx = +this.getAttribute("x") - d3.event.x;
|
||||||
const dy = +this.getAttribute("y") - d3.event.y;
|
const dy = +this.getAttribute("y") - d3.event.y;
|
||||||
|
|
||||||
d3.event.on("drag", function() {
|
d3.event.on("drag", function () {
|
||||||
const x = d3.event.x, y = d3.event.y;
|
const x = d3.event.x,
|
||||||
this.setAttribute("x", dx+x);
|
y = d3.event.y;
|
||||||
this.setAttribute("y", dy+y);
|
this.setAttribute("x", dx + x);
|
||||||
|
this.setAttribute("y", dy + y);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreEditMode() {
|
function restoreEditMode() {
|
||||||
if (!reliefTools.querySelector("button.pressed")) enterIndividualMode(); else
|
if (!reliefTools.querySelector("button.pressed")) enterIndividualMode();
|
||||||
if (reliefBulkAdd.classList.contains("pressed")) enterBulkAddMode(); else
|
else if (reliefBulkAdd.classList.contains("pressed")) enterBulkAddMode();
|
||||||
if (reliefBulkRemove.classList.contains("pressed")) enterBulkRemoveMode();
|
else if (reliefBulkRemove.classList.contains("pressed")) enterBulkRemoveMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateReliefIconSelected() {
|
function updateReliefIconSelected() {
|
||||||
const type = elSelected.attr("href") || elSelected.attr("data-type");
|
const type = elSelected.attr("href") || elSelected.attr("data-type");
|
||||||
const button = reliefIconsDiv.querySelector("svg[data-type='"+type+"']");
|
const button = reliefIconsDiv.querySelector("svg[data-type='" + type + "']");
|
||||||
|
|
||||||
reliefIconsDiv.querySelectorAll("svg.pressed").forEach(b => b.classList.remove("pressed"));
|
reliefIconsDiv.querySelectorAll("svg.pressed").forEach(b => b.classList.remove("pressed"));
|
||||||
button.classList.add("pressed");
|
button.classList.add("pressed");
|
||||||
reliefIconsDiv.querySelectorAll("div").forEach(b => b.style.display = "none");
|
reliefIconsDiv.querySelectorAll("div").forEach(b => (b.style.display = "none"));
|
||||||
button.parentNode.style.display = "block";
|
button.parentNode.style.display = "block";
|
||||||
reliefEditorSet.value = button.parentNode.dataset.type;
|
reliefEditorSet.value = button.parentNode.dataset.type;
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +81,7 @@ function editReliefIcon() {
|
||||||
reliefSpacingDiv.style.display = "none";
|
reliefSpacingDiv.style.display = "none";
|
||||||
reliefIconsSeletionAny.style.display = "none";
|
reliefIconsSeletionAny.style.display = "none";
|
||||||
|
|
||||||
|
removeCircle();
|
||||||
updateReliefSizeInput();
|
updateReliefSizeInput();
|
||||||
restoreDefaultEvents();
|
restoreDefaultEvents();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
|
|
@ -93,7 +97,8 @@ function editReliefIcon() {
|
||||||
reliefIconsSeletionAny.style.display = "none";
|
reliefIconsSeletionAny.style.display = "none";
|
||||||
|
|
||||||
const pressedType = reliefIconsDiv.querySelector("svg.pressed");
|
const pressedType = reliefIconsDiv.querySelector("svg.pressed");
|
||||||
if (pressedType.id === "reliefIconsSeletionAny") { // in "any" is pressed, select first type
|
if (pressedType.id === "reliefIconsSeletionAny") {
|
||||||
|
// in "any" is pressed, select first type
|
||||||
reliefIconsSeletionAny.classList.remove("pressed");
|
reliefIconsSeletionAny.classList.remove("pressed");
|
||||||
reliefIconsDiv.querySelector("svg").classList.add("pressed");
|
reliefIconsDiv.querySelector("svg").classList.add("pressed");
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +116,7 @@ function editReliefIcon() {
|
||||||
|
|
||||||
function dragToAdd() {
|
function dragToAdd() {
|
||||||
const pressed = reliefIconsDiv.querySelector("svg.pressed");
|
const pressed = reliefIconsDiv.querySelector("svg.pressed");
|
||||||
if (!pressed) {tip("Please select an icon", false, error); return;}
|
if (!pressed) return tip("Please select an icon", false, error);
|
||||||
|
|
||||||
const type = pressed.dataset.type;
|
const type = pressed.dataset.type;
|
||||||
const r = +reliefRadiusNumber.value;
|
const r = +reliefRadiusNumber.value;
|
||||||
|
|
@ -121,7 +126,7 @@ function editReliefIcon() {
|
||||||
// build a quadtree
|
// build a quadtree
|
||||||
const tree = d3.quadtree();
|
const tree = d3.quadtree();
|
||||||
const positions = [];
|
const positions = [];
|
||||||
terrain.selectAll("use").each(function() {
|
terrain.selectAll("use").each(function () {
|
||||||
const x = +this.getAttribute("x") + this.getAttribute("width") / 2;
|
const x = +this.getAttribute("x") + this.getAttribute("width") / 2;
|
||||||
const y = +this.getAttribute("y") + this.getAttribute("height") / 2;
|
const y = +this.getAttribute("y") + this.getAttribute("height") / 2;
|
||||||
tree.add([x, y, x]);
|
tree.add([x, y, x]);
|
||||||
|
|
@ -129,11 +134,11 @@ function editReliefIcon() {
|
||||||
positions.push(box.y + box.height);
|
positions.push(box.y + box.height);
|
||||||
});
|
});
|
||||||
|
|
||||||
d3.event.on("drag", function() {
|
d3.event.on("drag", function () {
|
||||||
const p = d3.mouse(this);
|
const p = d3.mouse(this);
|
||||||
moveCircle(p[0], p[1], r);
|
moveCircle(p[0], p[1], r);
|
||||||
|
|
||||||
d3.range(Math.ceil(r/10)).forEach(function() {
|
d3.range(Math.ceil(r / 10)).forEach(function () {
|
||||||
const a = Math.PI * 2 * Math.random();
|
const a = Math.PI * 2 * Math.random();
|
||||||
const rad = r * Math.random();
|
const rad = r * Math.random();
|
||||||
const cx = p[0] + rad * Math.cos(a);
|
const cx = p[0] + rad * Math.cos(a);
|
||||||
|
|
@ -142,21 +147,27 @@ function editReliefIcon() {
|
||||||
if (tree.find(cx, cy, spacing)) return; // too close to existing icon
|
if (tree.find(cx, cy, spacing)) return; // too close to existing icon
|
||||||
if (pack.cells.h[findCell(cx, cy)] < 20) return; // on water cell
|
if (pack.cells.h[findCell(cx, cy)] < 20) return; // on water cell
|
||||||
|
|
||||||
const h = rn(size / 2 * (Math.random() * .4 + .8), 2);
|
const h = rn((size / 2) * (Math.random() * 0.4 + 0.8), 2);
|
||||||
const x = rn(cx-h, 2);
|
const x = rn(cx - h, 2);
|
||||||
const y = rn(cy-h, 2);
|
const y = rn(cy - h, 2);
|
||||||
const z = y + h * 2;
|
const z = y + h * 2;
|
||||||
const s = rn(h*2, 2);
|
const s = rn(h * 2, 2);
|
||||||
|
|
||||||
let nth = 1;
|
let nth = 1;
|
||||||
while (positions[nth] && z > positions[nth]) {nth++;}
|
while (positions[nth] && z > positions[nth]) {
|
||||||
|
nth++;
|
||||||
|
}
|
||||||
|
|
||||||
tree.add([cx, cy]);
|
tree.add([cx, cy]);
|
||||||
positions.push(z);
|
positions.push(z);
|
||||||
terrain.insert("use", ":nth-child("+nth+")").attr("href", type)
|
terrain
|
||||||
.attr("x", x).attr("y", y).attr("width", s).attr("height", s);
|
.insert("use", ":nth-child(" + nth + ")")
|
||||||
|
.attr("href", type)
|
||||||
|
.attr("x", x)
|
||||||
|
.attr("y", y)
|
||||||
|
.attr("width", s)
|
||||||
|
.attr("height", s);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,25 +180,25 @@ function editReliefIcon() {
|
||||||
reliefSpacingDiv.style.display = "none";
|
reliefSpacingDiv.style.display = "none";
|
||||||
reliefIconsSeletionAny.style.display = "inline-block";
|
reliefIconsSeletionAny.style.display = "inline-block";
|
||||||
|
|
||||||
viewbox.style("cursor", "crosshair").call(d3.drag().on("start", dragToRemove)).on("touchmove mousemove", moveBrush);;
|
viewbox.style("cursor", "crosshair").call(d3.drag().on("start", dragToRemove)).on("touchmove mousemove", moveBrush);
|
||||||
tip("Drag to remove relief icons in radius", true);
|
tip("Drag to remove relief icons in radius", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragToRemove() {
|
function dragToRemove() {
|
||||||
const pressed = reliefIconsDiv.querySelector("svg.pressed");
|
const pressed = reliefIconsDiv.querySelector("svg.pressed");
|
||||||
if (!pressed) {tip("Please select an icon", false, error); return;}
|
if (!pressed) return tip("Please select an icon", false, error);
|
||||||
|
|
||||||
const r = +reliefRadiusNumber.value;
|
const r = +reliefRadiusNumber.value;
|
||||||
const type = pressed.dataset.type;
|
const type = pressed.dataset.type;
|
||||||
const icons = type ? terrain.selectAll("use[href='"+type+"']") : terrain.selectAll("use");
|
const icons = type ? terrain.selectAll("use[href='" + type + "']") : terrain.selectAll("use");
|
||||||
const tree = d3.quadtree();
|
const tree = d3.quadtree();
|
||||||
icons.each(function() {
|
icons.each(function () {
|
||||||
const x = +this.getAttribute("x") + this.getAttribute("width") / 2;
|
const x = +this.getAttribute("x") + this.getAttribute("width") / 2;
|
||||||
const y = +this.getAttribute("y") + this.getAttribute("height") / 2;
|
const y = +this.getAttribute("y") + this.getAttribute("height") / 2;
|
||||||
tree.add([x, y, this]);
|
tree.add([x, y, this]);
|
||||||
});
|
});
|
||||||
|
|
||||||
d3.event.on("drag", function() {
|
d3.event.on("drag", function () {
|
||||||
const p = d3.mouse(this);
|
const p = d3.mouse(this);
|
||||||
moveCircle(p[0], p[1], r);
|
moveCircle(p[0], p[1], r);
|
||||||
tree.findAll(p[0], p[1], r).forEach(f => f[2].remove());
|
tree.findAll(p[0], p[1], r).forEach(f => f[2].remove());
|
||||||
|
|
@ -200,20 +211,21 @@ function editReliefIcon() {
|
||||||
|
|
||||||
const shift = (size - +elSelected.attr("width")) / 2;
|
const shift = (size - +elSelected.attr("width")) / 2;
|
||||||
elSelected.attr("width", size).attr("height", size);
|
elSelected.attr("width", size).attr("height", size);
|
||||||
const x = +elSelected.attr("x"), y = +elSelected.attr("y");
|
const x = +elSelected.attr("x"),
|
||||||
elSelected.attr("x", x-shift).attr("y", y-shift);
|
y = +elSelected.attr("y");
|
||||||
|
elSelected.attr("x", x - shift).attr("y", y - shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIconsSet() {
|
function changeIconsSet() {
|
||||||
const set = reliefEditorSet.value;
|
const set = reliefEditorSet.value;
|
||||||
reliefIconsDiv.querySelectorAll("div").forEach(b => b.style.display = "none");
|
reliefIconsDiv.querySelectorAll("div").forEach(b => (b.style.display = "none"));
|
||||||
reliefIconsDiv.querySelector("div[data-type='" + set + "']").style.display = "block";
|
reliefIconsDiv.querySelector("div[data-type='" + set + "']").style.display = "block";
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeIcon() {
|
function changeIcon() {
|
||||||
if (this.classList.contains("pressed")) return;
|
if (this.classList.contains("pressed")) return;
|
||||||
|
|
||||||
reliefIconsDiv.querySelectorAll("svg.pressed").forEach(b => b.classList.remove("pressed"))
|
reliefIconsDiv.querySelectorAll("svg.pressed").forEach(b => b.classList.remove("pressed"));
|
||||||
this.classList.add("pressed");
|
this.classList.add("pressed");
|
||||||
|
|
||||||
if (reliefIndividual.classList.contains("pressed")) {
|
if (reliefIndividual.classList.contains("pressed")) {
|
||||||
|
|
@ -226,9 +238,11 @@ function editReliefIcon() {
|
||||||
const parent = elSelected.node().parentNode;
|
const parent = elSelected.node().parentNode;
|
||||||
const copy = elSelected.node().cloneNode(true);
|
const copy = elSelected.node().cloneNode(true);
|
||||||
|
|
||||||
let x = +elSelected.attr("x") - 3, y = +elSelected.attr("y") - 3;
|
let x = +elSelected.attr("x") - 3,
|
||||||
while (parent.querySelector("[x='"+x+"']","[x='"+y+"']")) {
|
y = +elSelected.attr("y") - 3;
|
||||||
x -= 3; y -= 3;
|
while (parent.querySelector("[x='" + x + "']", "[x='" + y + "']")) {
|
||||||
|
x -= 3;
|
||||||
|
y -= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy.setAttribute("x", x);
|
copy.setAttribute("x", x);
|
||||||
|
|
@ -237,15 +251,30 @@ function editReliefIcon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeIcon() {
|
function removeIcon() {
|
||||||
alertMessage.innerHTML = `Are you sure you want to remove the icon?`;
|
let selection = null;
|
||||||
$("#alert").dialog({resizable: false, title: "Remove relief icon",
|
const pressed = reliefTools.querySelector("button.pressed");
|
||||||
|
if (pressed.id === "reliefIndividual") {
|
||||||
|
alertMessage.innerHTML = `Are you sure you want to remove the icon?`;
|
||||||
|
selection = elSelected;
|
||||||
|
} else {
|
||||||
|
const type = reliefIconsDiv.querySelector("svg.pressed")?.dataset.type;
|
||||||
|
selection = type ? terrain.selectAll("use[href='" + type + "']") : terrain.selectAll("use");
|
||||||
|
const size = selection.size();
|
||||||
|
alertMessage.innerHTML = type ? `Are you sure you want to remove all ${type} icons (${size})?` : `Are you sure you want to remove all icons (${size})?`;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#alert").dialog({
|
||||||
|
resizable: false,
|
||||||
|
title: "Remove relief icons",
|
||||||
buttons: {
|
buttons: {
|
||||||
Remove: function() {
|
Remove: function () {
|
||||||
|
if (selection) selection.remove();
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
elSelected.remove();
|
|
||||||
$("#reliefEditor").dialog("close");
|
$("#reliefEditor").dialog("close");
|
||||||
},
|
},
|
||||||
Cancel: function() {$(this).dialog("close");}
|
Cancel: function () {
|
||||||
|
$(this).dialog("close");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -256,5 +285,4 @@ function editReliefIcon() {
|
||||||
unselect();
|
unselect();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue