start of ruler preferences and style

- Want to have initial X position.
- initial Y position.
- initial ruler lenght.

pending:

- Don't overlap at creation.
- change polyline width.
- change white and gray polyline.
- Change polyline color.
- Change text label.
- Change text font family.
- Change text font size.
This commit is contained in:
Ángel Montero Lamas 2024-08-27 22:19:17 +02:00
parent 19f7f2508e
commit 8b4dcec79d
5 changed files with 166 additions and 17 deletions

View file

@ -1181,6 +1181,17 @@
</tr>
</tbody>
<tbody id="styleStrokeWidthRuler">
<tr data-tip="Set stroke width for ruler lines">
<td>Stroke width</td>
<td>
<slider-input id="styleStrokeWidthInput" min="0" max="5" step=".01"></slider-input>
<input id="styleStrokeWidthWhiteInput" type="number" min="0" max="5" step=".01"></slider-input>
<input id="styleStrokeWidthGrayInput" type="number" min="0" max="5" step=".01"></slider-input>
</td>
</tr>
</tbody>
<tbody id="styleStrokeDash">
<tr data-tip="Set stroke dash array (e.g. 5 2) and linecap">
<td>Stroke dash</td>
@ -1412,6 +1423,21 @@
</tr>
</tbody>
<tbody id="styleRuler">
<tr data-tip="Set ruler initial X position">
<td><label for="rulerInitialX">Initial X position (%):</label></td>
<td><input type="number" id="rulerInitialX" min="0" max="100" step="1"></td>
</tr>
<tr data-tip="Set ruler initial Y position">
<td><label for="rulerInitialY">Initial Y position (%):</label></td>
<td><input type="number" id="rulerInitialY" min="0" max="100" step="1"></td>
</tr>
<tr data-tip="Set ruler initial length">
<td><label for="rulerInitialLength">Initial Length (%):</label></td>
<td><input type="number" id="rulerInitialLength" min="1" max="100" step="1"></td>
</tr>
</tbody>
<tbody id="styleScaleBar">
<tr data-tip="Set bar and font size">
<td>Size</td>

View file

@ -256,6 +256,10 @@ async function parseLoadedData(data, mapVersion) {
if (data[2]) mapCoordinates = JSON.parse(data[2]);
if (data[4]) notes = JSON.parse(data[4]);
if (data[33]) rulers.fromString(data[33]);
const rulerPreferences = JSON.parse(data[33]);
localStorage.setItem("rulerInitialX", rulerPreferences.initialX);
localStorage.setItem("rulerInitialY", rulerPreferences.initialY);
localStorage.setItem("rulerInitialLength", rulerPreferences.initialLength);
if (data[34]) {
const usedFonts = JSON.parse(data[34]);
usedFonts.forEach(usedFont => {

View file

@ -73,6 +73,11 @@ function prepareMapData() {
const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
const notesData = JSON.stringify(notes);
const rulerPreferences = JSON.stringify({
initialX: localStorage.getItem("rulerInitialX") || "50",
initialY: localStorage.getItem("rulerInitialY") || "50",
initialLength: localStorage.getItem("rulerInitialLength") || "100"
});
const rulersString = rulers.toString();
const fonts = JSON.stringify(getUsedFonts(svg.node()));
@ -148,6 +153,7 @@ function prepareMapData() {
provinces,
namesData,
rivers,
rulerPreferences,
rulersString,
fonts,
markers,

View file

@ -75,8 +75,15 @@ styleElementSelect.addEventListener("change", selectStyleElement);
function selectStyleElement() {
const styleElement = styleElementSelect.value;
console.log("Selecting style for element:", styleElement);
let el = d3.select("#" + styleElement);
// if element not found, return
if (!el.node()) {
console.warn(`Element ${styleElement} not found`);
return;
}
styleElements.querySelectorAll("tbody").forEach(e => (e.style.display = "none")); // hide all sections
// show alert line if layer is not visible
@ -84,14 +91,14 @@ function selectStyleElement() {
styleIsOff.style.display = isLayerOff ? "block" : "none";
// active group element
if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders", "terrs"].includes(styleElement)) {
if (["anchors", "borders", "burgIcons", "coastline", "labels", "lakes", "routes", "ruler", "terrs"].includes(styleElement)) {
const group = styleGroupSelect.value;
const defaultGroupSelector = styleElement === "terrs" ? "#landHeights" : "g";
el = group && el.select("#" + group).size() ? el.select("#" + group) : el.select(defaultGroupSelector);
}
// opacity
if (!["landmass", "ocean", "regions", "legend"].includes(styleElement)) {
if (!["landmass", "legend", "ocean", "regions"].includes(styleElement)) {
styleOpacity.style.display = "block";
styleOpacityInput.value = el.attr("opacity") || 1;
}
@ -103,7 +110,7 @@ function selectStyleElement() {
}
// fill
if (["rivers", "lakes", "landmass", "prec", "ice", "fogging", "scaleBar", "vignette"].includes(styleElement)) {
if (["fogging", "ice", "lakes", "landmass", "prec", "rivers", "scaleBar", "vignette"].includes(styleElement)) {
styleFill.style.display = "block";
styleFillInput.value = styleFillOutput.value = el.attr("fill");
}
@ -112,19 +119,20 @@ function selectStyleElement() {
if (
[
"armies",
"routes",
"lakes",
"borders",
"cults",
"relig",
"cells",
"coastline",
"prec",
"coordinates",
"cults",
"gridOverlay",
"ice",
"icons",
"coordinates",
"lakes",
"prec",
"relig",
"routes",
"ruler",
"zones",
"gridOverlay"
].includes(styleElement)
) {
styleStroke.style.display = "block";
@ -135,7 +143,7 @@ function selectStyleElement() {
// stroke dash
if (
["routes", "borders", "temperature", "legend", "population", "coordinates", "zones", "gridOverlay"].includes(
["borders", "coordinates", "gridOverlay", "legend", "population", "ruler", "routes", "temperature", "zones"].includes(
styleElement
)
) {
@ -344,9 +352,52 @@ function selectStyleElement() {
emblemsBurgSizeInput.value = emblems.select("#burgEmblems").attr("data-size") || 1;
}
/* if (styleElement === "ruler") {
// styleRulers.style.display = "block";
styleSelectFont.value = el.attr("font-family");
styleFontSize.value = el.attr("data-size");
} */
if (styleElement === "ruler") {
styleRuler.style.display = "block";
styleStroke.style.display = "block";
styleStrokeInput.value = styleStrokeOutput.value = el.select("polyline").attr("stroke");
styleStrokeWidthRuler.style.display = "block";
styleStrokeWidthInput.value = el.select("polyline").attr("stroke-width") || 0;
styleStrokeWidthWhiteInput.value = el.select("polyline.white").attr("stroke-width") || 0;
styleStrokeWidthGrayInput.value = el.select("polyline.gray").attr("stroke-width") || 0;
styleStrokeDash.style.display = "block";
styleStrokeDasharrayInput.value = el.select("polyline").attr("stroke-dasharray") || "";
styleStrokeLinecapInput.value = el.select("polyline").attr("stroke-linecap") || "inherit";
styleFont.style.display = "block";
styleSelectFont.value = el.select("text").attr("font-family") || "inherit";
styleFontSize.value = el.select("text").attr("font-size") || "10px";
// Mostrar los controles de preferencias del ruler
const styleRulerInitialX = document.getElementById("rulerInitialX");
const styleRulerInitialY = document.getElementById("rulerInitialY");
const styleRulerInitialLength = document.getElementById("rulerInitialLength");
if (styleRulerInitialX) {
styleRulerInitialX.style.display = "block";
styleRulerInitialX.value = localStorage.getItem("rulerInitialX") || "50";
}
if (styleRulerInitialY) {
styleRulerInitialY.style.display = "block";
styleRulerInitialY.value = localStorage.getItem("rulerInitialY") || "50";
}
if (styleRulerInitialLength) {
styleRulerInitialLength.style.display = "block";
styleRulerInitialLength.value = localStorage.getItem("rulerInitialLength") || "100";
}
}
// update group options
styleGroupSelect.options.length = 0; // remove all options
if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders", "terrs"].includes(styleElement)) {
if (["anchors", "borders", "burgIcons", "coastline", "labels", "lakes", "routes", "ruler", "terrs"].includes(styleElement)) {
const groups = byId(styleElement).querySelectorAll("g");
groups.forEach(el => {
if (el.id === "burgLabels") return;
@ -427,9 +478,36 @@ styleStrokeInput.addEventListener("input", function () {
if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
});
styleStrokeWidthInput.addEventListener("input", e => {
const styleStrokeWidthInput = document.getElementById('styleStrokeWidthInput');
if (styleStrokeWidthInput && styleStrokeWidthInput.querySelector('input')) {
styleStrokeWidthInput.querySelector('input').addEventListener("input", e => {
getEl().attr("stroke-width", e.target.value);
if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
});
} else {
console.warn('styleStrokeWidthInput not found or does not contain an input element');
}
/* styleStrokeWidthInput.addEventListener("input", e => {
getEl().attr("stroke-width", e.target.value);
if (styleElementSelect.value === "gridOverlay" && layerIsOn("toggleGrid")) drawGrid();
if (styleElementSelect.value === "ruler") {
getEl().select("polyline").attr("stroke-width", e.target.value);
}
}); */
styleStrokeWidthWhiteInput.addEventListener("input", e => {
const el = getEl();
if (el) {
el.selectAll("polyline.white").attr("stroke-width", e.target.value);
}
});
styleStrokeWidthGrayInput.addEventListener("input", e => {
const el = getEl();
if (el) {
el.selectAll("polyline.gray").attr("stroke-width", e.target.value);
}
});
styleStrokeDasharrayInput.addEventListener("input", function () {
@ -1075,6 +1153,30 @@ styleVignetteBlur.addEventListener("input", e => {
byId("vignette-rect")?.setAttribute("filter", `blur(${e.target.value}px)`);
});
document.addEventListener('DOMContentLoaded', function() {
const rulerInitialX = document.getElementById("rulerInitialX");
const rulerInitialY = document.getElementById("rulerInitialY");
const rulerInitialLength = document.getElementById("rulerInitialLength");
if (rulerInitialX) {
rulerInitialX.addEventListener("change", e => {
localStorage.setItem("rulerInitialX", e.target.value);
});
}
if (rulerInitialY) {
rulerInitialY.addEventListener("change", e => {
localStorage.setItem("rulerInitialY", e.target.value);
});
}
if (rulerInitialLength) {
rulerInitialLength.addEventListener("change", e => {
localStorage.setItem("rulerInitialLength", e.target.value);
});
}
});
styleScaleBar.addEventListener("input", function (event) {
const scaleBarBack = scaleBar.select("#scaleBarBack");
if (!scaleBarBack.size()) return;

View file

@ -122,12 +122,23 @@ function editUnits() {
function addRuler() {
if (!layerIsOn("toggleRulers")) toggleRulers();
const pt = byId("map").createSVGPoint();
(pt.x = graphWidth / 2), (pt.y = graphHeight / 4);
// Use saved values on localStorage, or default values if not exist
const initialX = parseFloat(localStorage.getItem("rulerInitialX")) || 50;
const initialY = parseFloat(localStorage.getItem("rulerInitialY")) || 50;
const initialLength = parseFloat(localStorage.getItem("rulerInitialLength")) || 100;
// Calculate coordinates based on percentages
pt.x = graphWidth * (initialX / 100);
pt.y = graphHeight * (initialY / 100);
// const defaultvalue = (pt.x = graphWidth / 2), (pt.y = graphHeight / 4);
const p = pt.matrixTransform(viewbox.node().getScreenCTM().inverse());
const dx = graphWidth / 4 / scale;
const dx = (initialLength / 200) * graphWidth / scale;
const dy = (rulers.data.length * 40) % (graphHeight / 2);
const from = [(p.x - dx) | 0, (p.y + dy) | 0];
const to = [(p.x + dx) | 0, (p.y + dy) | 0];
const from = [(p.x - dx) | 0, p.y | 0];
const to = [(p.x + dx) | 0, p.y | 0];
rulers.create(Ruler, [from, to]).draw();
}