From 043f71c1740d1ebe3a89ce30f68769ac7451d3ff Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 23 Oct 2021 15:19:34 +0300 Subject: [PATCH] fix scaleBar on svg export --- index.html | 6 +++--- modules/export.js | 14 +++++++++----- modules/ui/3d.js | 8 +++++--- modules/ui/measurers.js | 38 ++++++++++++++++++++++++-------------- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/index.html b/index.html index b92ba7bf..4bf6025b 100644 --- a/index.html +++ b/index.html @@ -3608,17 +3608,17 @@

Map will be split into tiles and downloaded as a single zip file. Avoid saving to big images

Columns:
- +
Rows:
- +
Scale:
- +
diff --git a/modules/export.js b/modules/export.js index 66c004b2..86e746cd 100644 --- a/modules/export.js +++ b/modules/export.js @@ -4,7 +4,7 @@ // download map as SVG async function saveSVG() { TIME && console.time("saveSVG"); - const url = await getMapURL("svg"); + const url = await getMapURL("svg", {fullMap: true}); const link = document.createElement("a"); link.download = getFileName() + ".svg"; link.href = url; @@ -74,7 +74,7 @@ async function saveJPEG() { async function saveTiles() { return new Promise(async (resolve, reject) => { // download schema - const urlSchema = await getMapURL("tiles", {debug: true}); + const urlSchema = await getMapURL("tiles", {debug: true, fullMap: true}); const zip = new JSZip(); const canvas = document.createElement("canvas"); @@ -90,7 +90,7 @@ async function saveTiles() { }; // download tiles - const url = await getMapURL("tiles"); + const url = await getMapURL("tiles", {fullMap: true}); const tilesX = +document.getElementById("tileColsInput").value; const tilesY = +document.getElementById("tileRowsInput").value; const scale = +document.getElementById("tileScaleInput").value; @@ -139,7 +139,10 @@ async function saveTiles() { // parse map svg to object url async function getMapURL(type, options = {}) { - const {debug = false, globe = false, noLabels = false, noWater = false} = options; + const {debug = false, globe = false, noLabels = false, noWater = false, fullMap = false} = options; + + if (fullMap) drawScaleBar(1); + const cloneEl = document.getElementById("map").cloneNode(true); // clone svg cloneEl.id = "fantasyMap"; document.body.appendChild(cloneEl); @@ -161,10 +164,11 @@ async function getMapURL(type, options = {}) { clone.select("#oceanBase").attr("opacity", 0); clone.select("#oceanPattern").attr("opacity", 0); } - if (type !== "png") { + if (fullMap) { // reset transform to show the whole map clone.attr("width", graphWidth).attr("height", graphHeight); clone.select("#viewbox").attr("transform", null); + drawScaleBar(scale); } if (type === "svg") removeUnusedElements(clone); diff --git a/modules/ui/3d.js b/modules/ui/3d.js index a2d52f57..3135c6e1 100644 --- a/modules/ui/3d.js +++ b/modules/ui/3d.js @@ -391,7 +391,8 @@ window.ThreeD = (function () { async function createMesh(width, height, segmentsX, segmentsY) { const mapOptions = { noLabels: options.labels3d, - noWater: options.extendedWater + noWater: options.extendedWater, + fullMap: true }; const url = await getMapURL("mesh", mapOptions); window.setTimeout(() => window.URL.revokeObjectURL(url), 5000); @@ -445,7 +446,8 @@ window.ThreeD = (function () { if (texture) texture.dispose(); const mapOptions = { noLabels: options.labels3d, - noWater: options.extendedWater + noWater: options.extendedWater, + fullMap: true }; const url = await getMapURL("mesh", mapOptions); window.setTimeout(() => window.URL.revokeObjectURL(url), 4000); @@ -526,7 +528,7 @@ window.ThreeD = (function () { material.map = texture; if (addMesh) addGlobe3dMesh(); }; - img2.src = await getMapURL("mesh", {globe: true}); + img2.src = await getMapURL("mesh", {globe: true, fullMap: true}); } async function getOBJ() { diff --git a/modules/ui/measurers.js b/modules/ui/measurers.js index 1d97a2d1..3fe8fe5b 100644 --- a/modules/ui/measurers.js +++ b/modules/ui/measurers.js @@ -20,7 +20,16 @@ class Rulers { for (const rulerString of rulers) { const [type, pointsString] = rulerString.split(": "); const points = pointsString.split(" ").map(el => el.split(",").map(n => +n)); - const Type = type === "Ruler" ? Ruler : type === "Opisometer" ? Opisometer : type === "RouteOpisometer" ? RouteOpisometer : type === "Planimeter" ? Planimeter : null; + const Type = + type === "Ruler" + ? Ruler + : type === "Opisometer" + ? Opisometer + : type === "RouteOpisometer" + ? RouteOpisometer + : type === "Planimeter" + ? Planimeter + : null; this.create(Type, points); } } @@ -527,17 +536,18 @@ class Planimeter extends Measurer { } // Scale bar -function drawScaleBar() { +function drawScaleBar(requestedScale) { if (scaleBar.style("display") === "none") return; // no need to re-draw hidden element scaleBar.selectAll("*").remove(); // fully redraw every time + const scaleLevel = requestedScale || scale; - const dScale = distanceScaleInput.value; + const distanceScale = distanceScaleInput.value; const unit = distanceUnitInput.value; + const size = +barSizeInput.value; // calculate size - const init = 100; // actual length in pixels if scale, dScale and size = 1; - const size = +barSizeInput.value; - let val = (init * size * dScale) / scale; // bar length in distance unit + const init = 100; + let val = (init * size * distanceScale) / scaleLevel; // bar length in distance unit if (val > 900) val = rn(val, -3); // round to 1000 else if (val > 90) val = rn(val, -2); @@ -545,13 +555,13 @@ function drawScaleBar() { else if (val > 9) val = rn(val, -1); // round to 10 else val = rn(val); // round to 1 - const l = (val * scale) / dScale; // actual length in pixels on this scale + const length = (val * scaleLevel) / distanceScale; // actual length in pixels on this scale scaleBar .append("line") .attr("x1", 0.5) .attr("y1", 0) - .attr("x2", l + size - 0.5) + .attr("x2", length + size - 0.5) .attr("y2", 0) .attr("stroke-width", size) .attr("stroke", "white"); @@ -559,16 +569,16 @@ function drawScaleBar() { .append("line") .attr("x1", 0) .attr("y1", size) - .attr("x2", l + size) + .attr("x2", length + size) .attr("y2", size) .attr("stroke-width", size) .attr("stroke", "#3d3d3d"); - const dash = size + " " + rn(l / 5 - size, 2); + const dash = size + " " + rn(length / 5 - size, 2); scaleBar .append("line") .attr("x1", 0) .attr("y1", 0) - .attr("x2", l + size) + .attr("x2", length + size) .attr("y2", 0) .attr("stroke-width", rn(size * 3, 2)) .attr("stroke-dasharray", dash) @@ -580,16 +590,16 @@ function drawScaleBar() { .data(d3.range(0, 6)) .enter() .append("text") - .attr("x", d => rn((d * l) / 5, 2)) + .attr("x", d => rn((d * length) / 5, 2)) .attr("y", 0) .attr("dy", "-.5em") .attr("font-size", fontSize) - .text(d => rn((((d * l) / 5) * dScale) / scale) + (d < 5 ? "" : " " + unit)); + .text(d => rn((((d * length) / 5) * distanceScale) / scaleLevel) + (d < 5 ? "" : " " + unit)); if (barLabel.value !== "") { scaleBar .append("text") - .attr("x", (l + 1) / 2) + .attr("x", (length + 1) / 2) .attr("y", 2 * size) .attr("dominant-baseline", "text-before-edge") .attr("font-size", fontSize)