v1.6.09 - rulers - support save/load

This commit is contained in:
Azgaar 2021-03-06 00:12:31 +03:00
parent 130cc7ebaf
commit 354830d4ec
5 changed files with 62 additions and 25 deletions

View file

@ -234,7 +234,7 @@
<div id="loading"> <div id="loading">
<div id="titleName"><t data-t="titleName">Azgaar's</t></div> <div id="titleName"><t data-t="titleName">Azgaar's</t></div>
<div id="title"><t data-t="title">Fantasy Map Generator</t></div> <div id="title"><t data-t="title">Fantasy Map Generator</t></div>
<div id="version"><t data-t="version">v. </t>1.6</div> <div id="version"><t data-t="version">v. </t>1.61</div>
<p id="loading-text"><t data-t="loading">LOADING</t><span>.</span><span>.</span><span>.</span></p> <p id="loading-text"><t data-t="loading">LOADING</t><span>.</span><span>.</span><span>.</span></p>
</div> </div>

View file

@ -2,7 +2,7 @@
// https://github.com/Azgaar/Fantasy-Map-Generator // https://github.com/Azgaar/Fantasy-Map-Generator
"use strict"; "use strict";
const version = "1.6"; // generator version const version = "1.61"; // generator version
document.title += " v" + version; document.title += " v" + version;
// Switches to disable/enable logging features // Switches to disable/enable logging features

View file

@ -323,6 +323,7 @@ function getMapData() {
const coords = JSON.stringify(mapCoordinates); const coords = JSON.stringify(mapCoordinates);
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|"); const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
const notesData = JSON.stringify(notes); const notesData = JSON.stringify(notes);
const rulersString = rulers.toString();
// clone svg // clone svg
const cloneEl = document.getElementById("map").cloneNode(true); const cloneEl = document.getElementById("map").cloneNode(true);
@ -332,6 +333,9 @@ function getMapData() {
cloneEl.setAttribute("height", graphHeight); cloneEl.setAttribute("height", graphHeight);
cloneEl.querySelector("#viewbox").removeAttribute("transform"); cloneEl.querySelector("#viewbox").removeAttribute("transform");
// always remove rulers
cloneEl.querySelector("#ruler").innerHTML = "";
const svg_xml = (new XMLSerializer()).serializeToString(cloneEl); const svg_xml = (new XMLSerializer()).serializeToString(cloneEl);
const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features}); const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features});
@ -360,7 +364,7 @@ function getMapData() {
pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl, pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl,
pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state, pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state,
pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces, pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces,
namesData, rivers].join("\r\n"); namesData, rivers, rulersString].join("\r\n");
const blob = new Blob([data], {type: "text/plain"}); const blob = new Blob([data], {type: "text/plain"});
TIME && console.timeEnd("createMapDataBlob"); TIME && console.timeEnd("createMapDataBlob");
@ -659,6 +663,7 @@ function parseLoadedData(data) {
void function parseConfiguration() { void function parseConfiguration() {
if (data[2]) mapCoordinates = JSON.parse(data[2]); if (data[2]) mapCoordinates = JSON.parse(data[2]);
if (data[4]) notes = JSON.parse(data[4]); if (data[4]) notes = JSON.parse(data[4]);
if (data[33]) rulers.fromString(data[33]);
const biomes = data[3].split("|"); const biomes = data[3].split("|");
biomesData = applyDefaultBiomesSystem(); biomesData = applyDefaultBiomesSystem();
@ -822,14 +827,6 @@ function parseLoadedData(data) {
}() }()
void function restoreEvents() { void function restoreEvents() {
ruler.selectAll("g").call(d3.drag().on("start", dragRuler));
ruler.selectAll("text").on("click", removeParent);
ruler.selectAll("g.ruler circle").call(d3.drag().on("drag", dragRulerEdge));
ruler.selectAll("g.ruler circle").call(d3.drag().on("drag", dragRulerEdge));
ruler.selectAll("g.ruler rect").call(d3.drag().on("start", rulerCenterDrag));
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
scaleBar.on("mousemove", () => tip("Click to open Units Editor")).on("click", () => editUnits()); scaleBar.on("mousemove", () => tip("Click to open Units Editor")).on("click", () => editUnits());
legend.on("mousemove", () => tip("Drag to change the position. Click to hide the legend")).on("click", () => clearLegend()); legend.on("mousemove", () => tip("Drag to change the position. Click to hide the legend")).on("click", () => clearLegend());
}() }()
@ -1136,6 +1133,45 @@ function parseLoadedData(data) {
// v 1.61 changed rulers data // v 1.61 changed rulers data
ruler.style("display", null); ruler.style("display", null);
rulers = new Rulers(); rulers = new Rulers();
ruler.selectAll(".ruler > .white").each(function() {
const x1 = +this.getAttribute("x1");
const y1 = +this.getAttribute("y1");
const x2 = +this.getAttribute("x2");
const y2 = +this.getAttribute("y2");
if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) return;
const points = [[x1, y1], [x2, y2]];
rulers.create(Ruler, points);
});
ruler.selectAll("g.opisometer").each(function() {
const pointsString = this.dataset.points;
if (!pointsString) return;
const points = JSON.parse(pointsString);
rulers.create(Opisometer, points);
});
ruler.selectAll("path.planimeter").each(function() {
const length = this.getTotalLength();
if (length < 30) return;
const step = length > 1000 ? 40 : length > 400 ? 20 : 10;
const increment = length / Math.ceil(length / step);
const points = [];
for (let i=0; i <= length; i += increment) {
const point = this.getPointAtLength(i);
points.push([point.x | 0, point.y | 0]);
}
rulers.create(Planimeter, points);
});
ruler.selectAll("*").remove();
if (rulers.data.length) {
turnButtonOn("toggleRulers");
rulers.draw();
} else turnButtonOff("toggleRulers");
} }
}() }()
@ -1222,6 +1258,9 @@ function parseLoadedData(data) {
// remove href from emblems, to trigger rendering on load // remove href from emblems, to trigger rendering on load
emblems.selectAll("use").attr("href", null); emblems.selectAll("use").attr("href", null);
// draw data layers (no kept in svg)
if (rulers && layerIsOn("toggleRulers")) rulers.draw();
// set options // set options
yearInput.value = options.year; yearInput.value = options.year;
eraInput.value = options.era; eraInput.value = options.era;

View file

@ -151,7 +151,7 @@ function drawHeightmap() {
} }
let currentLayer = 20; let currentLayer = 20;
const heights = cells.i.sort((a, b) => cells.h[a] - cells.h[b]); const heights = cells.i.sort((a, b) => cells.h[a] - cells.h[b]);
for (const i of heights) { for (const i of heights) {
const h = cells.h[i]; const h = cells.h[i];
if (h > currentLayer) currentLayer += skip; if (h > currentLayer) currentLayer += skip;
@ -200,7 +200,7 @@ function drawHeightmap() {
const n = simplification + 1; // filter each nth element const n = simplification + 1; // filter each nth element
return chain.filter((d, i) => i % n === 0); return chain.filter((d, i) => i % n === 0);
} }
TIME && console.timeEnd("drawHeightmap"); TIME && console.timeEnd("drawHeightmap");
} }
@ -240,7 +240,7 @@ function drawTemp() {
const used = new Uint8Array(n); // to detect already passed cells const used = new Uint8Array(n); // to detect already passed cells
const min = d3.min(cells.temp), max = d3.max(cells.temp); const min = d3.min(cells.temp), max = d3.max(cells.temp);
const step = Math.max(Math.round(Math.abs(min - max) / 5), 1); const step = Math.max(Math.round(Math.abs(min - max) / 5), 1);
const isolines = d3.range(min+step, max, step); const isolines = d3.range(min+step, max, step);
const chains = [], labels = []; // store label coordinates const chains = [], labels = []; // store label coordinates
for (const i of cells.i) { for (const i of cells.i) {
@ -557,7 +557,7 @@ function toggleCultures(event) {
function drawCultures() { function drawCultures() {
TIME && console.time("drawCultures"); TIME && console.time("drawCultures");
cults.selectAll("path").remove(); cults.selectAll("path").remove();
const cells = pack.cells, vertices = pack.vertices, cultures = pack.cultures, n = cells.i.length; const cells = pack.cells, vertices = pack.vertices, cultures = pack.cultures, n = cells.i.length;
const used = new Uint8Array(cells.i.length); const used = new Uint8Array(cells.i.length);
@ -738,7 +738,7 @@ function drawStates() {
const chain = []; // vertices chain to form a path const chain = []; // vertices chain to form a path
let land = vertices.c[start].some(c => cells.h[c] >= 20 && cells.state[c] !== t); let land = vertices.c[start].some(c => cells.h[c] >= 20 && cells.state[c] !== t);
function check(i) {state = cells.state[i]; land = cells.h[i] >= 20;} function check(i) {state = cells.state[i]; land = cells.h[i] >= 20;}
for (let i=0, current = start; i === 0 || current !== start && i < 20000; i++) { for (let i=0, current = start; i === 0 || current !== start && i < 20000; i++) {
const prev = chain[chain.length - 1] ? chain[chain.length - 1][0] : -1; // previous vertex in chain const prev = chain[chain.length - 1] ? chain[chain.length - 1][0] : -1; // previous vertex in chain
chain.push([current, state, land]); // add current vertex to sequence chain.push([current, state, land]); // add current vertex to sequence
@ -797,7 +797,7 @@ function drawBorders() {
sUsed[s][stateToCell] = stateTo; sUsed[s][stateToCell] = stateTo;
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] >= 20 && cells.state[i] === stateTo)); const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] >= 20 && cells.state[i] === stateTo));
const chain = connectVertices(vertex, s, cells.state, stateTo, sUsed); const chain = connectVertices(vertex, s, cells.state, stateTo, sUsed);
if (chain.length > 1) { if (chain.length > 1) {
sPath.push("M" + chain.map(c => vertices.p[c]).join(" ")); sPath.push("M" + chain.map(c => vertices.p[c]).join(" "));
i--; i--;
@ -819,7 +819,7 @@ function drawBorders() {
for (let i=0; i < 1000; i++) { for (let i=0; i < 1000; i++) {
if (i === 999) ERROR && console.error("Find starting vertex: limit is reached", current, f, t); if (i === 999) ERROR && console.error("Find starting vertex: limit is reached", current, f, t);
const p = chain[chain.length-2] || -1; // previous vertex const p = chain[chain.length-2] || -1; // previous vertex
const v = vertices.v[current], c = vertices.c[current]; const v = vertices.v[current], c = vertices.c[current];
const v0 = checkCell(c[0]) !== checkCell(c[1]) && checkVertex(v[0]); const v0 = checkCell(c[0]) !== checkCell(c[1]) && checkVertex(v[0]);
const v1 = checkCell(c[1]) !== checkCell(c[2]) && checkVertex(v[1]); const v1 = checkCell(c[1]) !== checkCell(c[2]) && checkVertex(v[1]);
@ -867,7 +867,7 @@ function toggleBorders(event) {
if (event && isCtrlClick(event)) {editStyle("borders"); return;} if (event && isCtrlClick(event)) {editStyle("borders"); return;}
turnButtonOff("toggleBorders"); turnButtonOff("toggleBorders");
$('#borders').fadeOut(); $('#borders').fadeOut();
} }
} }
function toggleProvinces(event) { function toggleProvinces(event) {
@ -1196,7 +1196,7 @@ function toggleIcons(event) {
if (event && isCtrlClick(event)) {editStyle("burgIcons"); return;} if (event && isCtrlClick(event)) {editStyle("burgIcons"); return;}
turnButtonOff("toggleIcons"); turnButtonOff("toggleIcons");
$('#icons').fadeOut(); $('#icons').fadeOut();
} }
} }
function toggleRulers(event) { function toggleRulers(event) {
@ -1204,10 +1204,12 @@ function toggleRulers(event) {
turnButtonOn("toggleRulers"); turnButtonOn("toggleRulers");
if (event && isCtrlClick(event)) editStyle("ruler"); if (event && isCtrlClick(event)) editStyle("ruler");
rulers.draw(); rulers.draw();
ruler.style("display", null);
} else { } else {
if (event && isCtrlClick(event)) {editStyle("ruler"); return;} if (event && isCtrlClick(event)) {editStyle("ruler"); return;}
turnButtonOff("toggleRulers"); turnButtonOff("toggleRulers");
rulers.undraw(); ruler.selectAll("*").remove();
ruler.style("display", "none");
} }
} }

View file

@ -240,10 +240,6 @@ class Ruler extends Measurer {
if (this.points.length < 2) context.el.remove(); if (this.points.length < 2) context.el.remove();
else context.draw(); else context.draw();
} }
undraw() {
this.el.remove();
}
} }
class Opisometer extends Measurer { class Opisometer extends Measurer {