diff --git a/script.js b/script.js index d87339a6..148c308c 100644 --- a/script.js +++ b/script.js @@ -28,36 +28,36 @@ function fantasyMap() { document.title += " v. " + version; // Declare variables - var svg = d3.select("svg"), - defs = svg.select("#deftemp"), - viewbox = svg.append("g").attr("id", "viewbox"), - ocean = viewbox.append("g").attr("id", "ocean"), - oceanLayers = ocean.append("g").attr("id", "oceanLayers"), - oceanPattern = ocean.append("g").attr("id", "oceanPattern"), - landmass = viewbox.append("g").attr("id", "landmass"), - terrs = viewbox.append("g").attr("id", "terrs"), - grid = viewbox.append("g").attr("id", "grid"), - overlay = viewbox.append("g").attr("id", "overlay"), - routes = viewbox.append("g").attr("id", "routes"), - roads = routes.append("g").attr("id", "roads").attr("data-type", "land"), - trails = routes.append("g").attr("id", "trails").attr("data-type", "land"), - rivers = viewbox.append("g").attr("id", "rivers"), - terrain = viewbox.append("g").attr("id", "terrain"), - cults = viewbox.append("g").attr("id", "cults"), - regions = viewbox.append("g").attr("id", "regions"), - borders = viewbox.append("g").attr("id", "borders"), - stateBorders = borders.append("g").attr("id", "stateBorders"), - neutralBorders = borders.append("g").attr("id", "neutralBorders"), - lakes = viewbox.append("g").attr("id", "lakes"), - coastline = viewbox.append("g").attr("id", "coastline"), - searoutes = routes.append("g").attr("id", "searoutes").attr("data-type", "sea"), - labels = viewbox.append("g").attr("id", "labels"), - burgLabels = labels.append("g").attr("id", "burgLabels"), - icons = viewbox.append("g").attr("id", "icons"), - burgIcons = icons.append("g").attr("id", "burgIcons"), - markers = viewbox.append("g").attr("id", "markers"), - ruler = viewbox.append("g").attr("id", "ruler"), - debug = viewbox.append("g").attr("id", "debug"); + let svg = d3.select("svg"); + let defs = svg.select("#deftemp"); + let viewbox = svg.append("g").attr("id", "viewbox"); + let ocean = viewbox.append("g").attr("id", "ocean"); + let oceanLayers = ocean.append("g").attr("id", "oceanLayers"); + let oceanPattern = ocean.append("g").attr("id", "oceanPattern"); + let landmass = viewbox.append("g").attr("id", "landmass"); + let terrs = viewbox.append("g").attr("id", "terrs"); + let grid = viewbox.append("g").attr("id", "grid"); + let overlay = viewbox.append("g").attr("id", "overlay"); + let routes = viewbox.append("g").attr("id", "routes"); + let roads = routes.append("g").attr("id", "roads").attr("data-type", "land"); + let trails = routes.append("g").attr("id", "trails").attr("data-type", "land"); + let rivers = viewbox.append("g").attr("id", "rivers"); + let terrain = viewbox.append("g").attr("id", "terrain"); + let cults = viewbox.append("g").attr("id", "cults"); + let regions = viewbox.append("g").attr("id", "regions"); + let borders = viewbox.append("g").attr("id", "borders"); + let stateBorders = borders.append("g").attr("id", "stateBorders"); + let neutralBorders = borders.append("g").attr("id", "neutralBorders"); + let lakes = viewbox.append("g").attr("id", "lakes"); + let coastline = viewbox.append("g").attr("id", "coastline"); + let searoutes = routes.append("g").attr("id", "searoutes").attr("data-type", "sea"); + let labels = viewbox.append("g").attr("id", "labels"); + let burgLabels = labels.append("g").attr("id", "burgLabels"); + let icons = viewbox.append("g").attr("id", "icons"); + let burgIcons = icons.append("g").attr("id", "burgIcons"); + let markers = viewbox.append("g").attr("id", "markers"); + let ruler = viewbox.append("g").attr("id", "ruler"); + let debug = viewbox.append("g").attr("id", "debug"); labels.append("g").attr("id", "countries"); burgIcons.append("g").attr("id", "capitals"); @@ -76,32 +76,61 @@ function fantasyMap() { oceanLayers.append("rect").attr("id", "oceanBase"); // main data variables - var seed, params, voronoi, diagram, polygons, spacing, points = [], heights; + let seed; + let params; + let voronoi; + let diagram; + let polygons; + let spacing; + let points = []; + let heights; // Common variables - var modules = {}, customization = 0, history = [], historyStage = 0, elSelected, autoResize = true, graphSize, - cells = [],land = [], riversData = [], manors = [], states = [], features = [], notes = [], - queue = [], fonts = ["Almendra+SC", "Georgia", "Times+New+Roman", "Comic+Sans+MS", "Lucida+Sans+Unicode", "Courier+New"]; + const modules = {}; + let customization = 0; + let history = []; + let historyStage = 0; + let elSelected; + let autoResize = true; + let graphSize; + let cells = []; + let land = []; + let riversData = []; + let manors = []; + let states = []; + let features = []; + let notes = []; + let queue = []; + const fonts = ["Almendra+SC", "Georgia", "Times+New+Roman", "Comic+Sans+MS", "Lucida+Sans+Unicode", "Courier+New"]; // Cultures-related data - var defaultCultures = [], cultures = [], chain = {}, nameBases = [], nameBase = [], cultureTree; + let defaultCultures = []; + let cultures = []; + const chain = {}; + let nameBases = []; + let nameBase = []; + let cultureTree; const vowels = "aeiouy"; // canvas element for raster images - var canvas = document.getElementById("canvas"), - ctx = canvas.getContext("2d"); + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext("2d"); // Color schemes - var color = d3.scaleSequential(d3.interpolateSpectral), - colors8 = d3.scaleOrdinal(d3.schemeSet2), - colors20 = d3.scaleOrdinal(d3.schemeCategory20); + let color = d3.scaleSequential(d3.interpolateSpectral); + const colors8 = d3.scaleOrdinal(d3.schemeSet2); + const colors20 = d3.scaleOrdinal(d3.schemeCategory20); // D3 drag and zoom behavior - var scale = 1, viewX = 0, viewY = 0; - var zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomed); + let scale = 1, viewX = 0, viewY = 0; + const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomed); svg.call(zoom); // D3 Line generator variables - var lineGen = d3.line().x(function(d) {return d.scX;}).y(function(d) {return d.scY;}).curve(d3.curveCatmullRom); + const lineGen = d3.line().x(function (d) { + return d.scX; + }).y(function (d) { + return d.scY; + }).curve(d3.curveCatmullRom); applyStoredOptions(); let graphWidth = +mapWidthInput.value; // voronoi graph extention, should be stable for each map @@ -123,13 +152,18 @@ function fantasyMap() { $("#templateBody").sortable({items: "div:not(div[data-type='Mountain'])"}); $("#mapLayers, #templateBody").disableSelection(); - var drag = d3.drag() - .container(function() {return this;}) - .subject(function() {var p=[d3.event.x, d3.event.y]; return [p, p];}) + const drag = d3.drag() + .container(function () { + return this; + }) + .subject(function () { + const p = [d3.event.x, d3.event.y]; + return [p, p]; + }) .on("start", dragstarted); function zoomed() { - var scaleDiff = Math.abs(scale - d3.event.transform.k); + const scaleDiff = Math.abs(scale - d3.event.transform.k); scale = d3.event.transform.k; viewX = d3.event.transform.x; viewY = d3.event.transform.y; @@ -204,7 +238,7 @@ function fantasyMap() { addDragToUpload(); // Changelog dialog window - var storedVersion = localStorage.getItem("version"); // show message on load + const storedVersion = localStorage.getItem("version"); // show message on load if (storedVersion != version) { alertMessage.innerHTML = `2018-29-23: The Fantasy Map Generator is updated up to version ${version}. @@ -620,21 +654,22 @@ function fantasyMap() { // Drag actions function dragstarted() { - var x0 = d3.event.x, y0 = d3.event.y, - c0 = diagram.find(x0, y0).index, c1 = c0; - var x1, y1; - var opisometer = $("#addOpisometer").hasClass("pressed"); - var planimeter = $("#addPlanimeter").hasClass("pressed"); - var factor = rn(1 / Math.pow(scale, 0.3), 1); + const x0 = d3.event.x, y0 = d3.event.y, + c0 = diagram.find(x0, y0).index; + let c1 = c0; + let x1, y1; + const opisometer = $("#addOpisometer").hasClass("pressed"); + const planimeter = $("#addPlanimeter").hasClass("pressed"); + const factor = rn(1 / Math.pow(scale, 0.3), 1); if (opisometer || planimeter) { $("#ruler").show(); - var type = opisometer ? "opisometer" : "planimeter"; + const type = opisometer ? "opisometer" : "planimeter"; var rulerNew = ruler.append("g").attr("class", type).call(d3.drag().on("start", elementDrag)); var points = [{scX: rn(x0, 2), scY: rn(y0, 2)}]; if (opisometer) { var curve = rulerNew.append("path").attr("class", "opisometer white").attr("stroke-width", factor); - var dash = rn(30 / distanceScale.value, 2); + const dash = rn(30 / distanceScale.value, 2); var curveGray = rulerNew.append("path").attr("class", "opisometer gray").attr("stroke-dasharray", dash).attr("stroke-width", factor); } else { var curve = rulerNew.append("path").attr("class", "planimeter").attr("stroke-width", factor); @@ -644,7 +679,7 @@ function fantasyMap() { d3.event.on("drag", function() { x1 = d3.event.x, y1 = d3.event.y; - var c2 = diagram.find(x1, y1).index; + const c2 = diagram.find(x1, y1).index; // Heightmap customization if (customization === 1) { @@ -678,16 +713,16 @@ function fantasyMap() { } if (opisometer || planimeter) { - var l = points[points.length - 1]; - var diff = Math.hypot(l.scX - x1, l.scY - y1); + const l = points[points.length - 1]; + const diff = Math.hypot(l.scX - x1, l.scY - y1); if (diff > 5) {points.push({scX: x1, scY: y1});} if (opisometer) { lineGen.curve(d3.curveBasis); var d = round(lineGen(points)); curve.attr("d", d); curveGray.attr("d", d); - var dist = rn(curve.node().getTotalLength()); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + const dist = rn(curve.node().getTotalLength()); + const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; text.attr("x", x1).attr("y", y1 - 10).text(label); } else { lineGen.curve(d3.curveBasisClosed); @@ -703,22 +738,24 @@ function fantasyMap() { $("#addOpisometer, #addPlanimeter").removeClass("pressed"); restoreDefaultEvents(); if (opisometer) { - var dist = rn(curve.node().getTotalLength()); + const dist = rn(curve.node().getTotalLength()); var c = curve.node().getPointAtLength(dist / 2); - var p = curve.node().getPointAtLength((dist / 2) - 1); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; - var atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); - var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + c.x + " " + c.y +")"; + const p = curve.node().getPointAtLength((dist / 2) - 1); + const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + const atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); + const angle = rn(atan * 180 / Math.PI, 3); + const tr = "rotate(" + angle + " " + c.x + " " + c.y + ")"; text.attr("data-points", JSON.stringify(points)).attr("data-dist", dist).attr("x", c.x).attr("y", c.y).attr("transform", tr).text(label).on("click", removeParent); rulerNew.append("circle").attr("cx", points[0].scX).attr("cy", points[0].scY).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor) .attr("data-edge", "start").call(d3.drag().on("start", opisometerEdgeDrag)); rulerNew.append("circle").attr("cx", points[points.length - 1].scX).attr("cy", points[points.length - 1].scY).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor) .attr("data-edge", "end").call(d3.drag().on("start", opisometerEdgeDrag)); } else { - var vertices = points.map(function(p) {return [p.scX, p.scY]}); - var area = rn(Math.abs(d3.polygonArea(vertices))); // initial area as positive integer - var areaConv = area * Math.pow(distanceScale.value, 2); // convert area to distanceScale + const vertices = points.map(function (p) { + return [p.scX, p.scY] + }); + const area = rn(Math.abs(d3.polygonArea(vertices))); // initial area as positive integer + let areaConv = area * Math.pow(distanceScale.value, 2); // convert area to distanceScale areaConv = si(areaConv); if (areaUnit.value === "square") {areaConv += " " + distanceUnit.value + "²"} else {areaConv += " " + areaUnit.value;} var c = polylabel([vertices],1.0); // pole of inaccessibility @@ -1039,7 +1076,9 @@ function fantasyMap() { function add(start, type, height) { const session = Math.ceil(Math.random() * 1e5); - let radius, hRadius, mRadius; + let radius; + let hRadius; + let mRadius; switch (+graphSize) { case 1: hRadius = 0.991; mRadius = 0.91; break; case 2: hRadius = 0.9967; mRadius = 0.951; break; @@ -1047,7 +1086,7 @@ function fantasyMap() { case 4: hRadius = 0.9994; mRadius = 0.98; break; } radius = type === "mountain" ? mRadius : hRadius; - var queue = [start]; + const queue = [start]; if (type === "mountain") heights[start] = height; for (let i=0; i < queue.length && height >= 1; i++) { if (type === "mountain") {height = heights[queue[i]] * radius - height / 100;} @@ -1064,26 +1103,26 @@ function fantasyMap() { } function addRange(mod, height, from, to) { - var session = Math.ceil(Math.random() * 100000); - var count = Math.abs(mod); + const session = Math.ceil(Math.random() * 100000); + const count = Math.abs(mod); let range = []; for (let c = 0; c < count; c++) { range = []; - var diff = 0, start = from, end = to; + let diff = 0, start = from, end = to; if (!start || !end) { do { - var xf = Math.floor(Math.random() * (graphWidth*0.7)) + graphWidth*0.15; - var yf = Math.floor(Math.random() * (graphHeight*0.6)) + graphHeight*0.2; + const xf = Math.floor(Math.random() * (graphWidth * 0.7)) + graphWidth * 0.15; + const yf = Math.floor(Math.random() * (graphHeight * 0.6)) + graphHeight * 0.2; start = diagram.find(xf, yf).index; - var xt = Math.floor(Math.random() * (graphWidth*0.7)) + graphWidth*0.15; - var yt = Math.floor(Math.random() * (graphHeight*0.6)) + graphHeight*0.2; + const xt = Math.floor(Math.random() * (graphWidth * 0.7)) + graphWidth * 0.15; + const yt = Math.floor(Math.random() * (graphHeight * 0.6)) + graphHeight * 0.2; end = diagram.find(xt, yt).index; diff = Math.hypot(xt - xf, yt - yf); } while (diff < 150 / graphSize || diff > 300 / graphSize) } if (start && end) { for (let l = 0; start != end && l < 10000; l++) { - var min = 10000; + let min = 10000; cells[start].neighbors.forEach(function(e) { diff = Math.hypot(cells[end].data[0] - cells[e].data[0],cells[end].data[1] - cells[e].data[1]); if (Math.random() > 0.8) diff = diff / 2; @@ -1092,7 +1131,7 @@ function fantasyMap() { range.push(start); } } - var change = height ? height : Math.random() * 10 + 10; + const change = height ? height : Math.random() * 10 + 10; range.map(function(r) { let rnd = Math.random() * 0.4 + 0.8; if (mod > 0) heights[r] += change * rnd; @@ -1112,14 +1151,14 @@ function fantasyMap() { } function addStrait(width) { - var session = Math.ceil(Math.random() * 100000); - var top = Math.floor(Math.random() * graphWidth * 0.35 + graphWidth * 0.3); - var bottom = Math.floor((graphWidth - top) - (graphWidth * 0.1) + (Math.random() * graphWidth * 0.2)); - var start = diagram.find(top, graphHeight * 0.1).index; - var end = diagram.find(bottom, graphHeight * 0.9).index; - var range = []; + const session = Math.ceil(Math.random() * 100000); + const top = Math.floor(Math.random() * graphWidth * 0.35 + graphWidth * 0.3); + const bottom = Math.floor((graphWidth - top) - (graphWidth * 0.1) + (Math.random() * graphWidth * 0.2)); + let start = diagram.find(top, graphHeight * 0.1).index; + const end = diagram.find(bottom, graphHeight * 0.9).index; + let range = []; for (let l = 0; start !== end && l < 1000; l++) { - var min = 10000; // dummy value + let min = 10000; // dummy value cells[start].neighbors.forEach(function(e) { let diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); if (Math.random() > 0.8) {diff = diff / 2} @@ -1127,7 +1166,7 @@ function fantasyMap() { }); range.push(start); } - var query = []; + const query = []; for (; width > 0; width--) { range.map(function(r) { cells[r].neighbors.forEach(function(e) { @@ -1627,12 +1666,14 @@ function fantasyMap() { if ($("#scaleBar").hasClass("hidden")) return; // no need to re-draw hidden element svg.select("#scaleBar").remove(); // fully redraw every time // get size - var size = +barSize.value; - var dScale = distanceScale.value; - var unit = distanceUnit.value; - var scaleBar = svg.append("g").attr("id", "scaleBar") + const size = +barSize.value; + const dScale = distanceScale.value; + const unit = distanceUnit.value; + const scaleBar = svg.append("g").attr("id", "scaleBar") .on("click", editScale) - .on("mousemove", function() {tip("Click to open Scale Editor, drag to move");}) + .on("mousemove", function () { + tip("Click to open Scale Editor, drag to move"); + }) .call(d3.drag().on("start", elementDrag)); const init = 100; // actual length in pixels if scale, dScale and size = 1; let val = init * size * dScale / scale; // bar length in distance unit @@ -1649,8 +1690,8 @@ function fantasyMap() { .attr("stroke-width", rn(size * 3, 2)).attr("stroke-dasharray", dash).attr("stroke", "#3d3d3d"); // big scale for (let b = 0; b < 6; b++) { - var value = rn(b * l / 5, 2); - var label = rn(value * dScale / scale); + const value = rn(b * l / 5, 2); + const label = rn(value * dScale / scale); if (b === 5) { scaleBar.append("text").attr("x", x + value).attr("y", y - 2 * size).attr("font-size", rn(5 * size, 1)).text(label + " " + unit); } else { @@ -1724,11 +1765,12 @@ function fantasyMap() { // draw ruler circles and update label function rulerEdgeDrag() { - var group = d3.select(this.parentNode); - var edge = d3.select(this).attr("data-edge"); - var x = d3.event.x, y = d3.event.y, x0, y0; + const group = d3.select(this.parentNode); + const edge = d3.select(this).attr("data-edge"); + const x = d3.event.x, y = d3.event.y; + let x0, y0; d3.select(this).attr("cx", x).attr("cy", y); - var line = group.selectAll("line"); + const line = group.selectAll("line"); if (edge === "left") { line.attr("x1", x).attr("y1", y); x0 = +line.attr("x2"), y0 = +line.attr("y2"); @@ -1736,28 +1778,28 @@ function fantasyMap() { line.attr("x2", x).attr("y2", y); x0 = +line.attr("x1"), y0 = +line.attr("y1"); } - var xc = rn((x + x0) / 2, 2), yc = rn((y + y0) / 2, 2); + const xc = rn((x + x0) / 2, 2), yc = rn((y + y0) / 2, 2); group.select(".center").attr("cx", xc).attr("cy", yc); - var dist = rn(Math.hypot(x0 - x, y0 - y)); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; - var atan = x0 > x ? Math.atan2(y0 - y, x0 - x) : Math.atan2(y - y0, x - x0); - var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + xc + " " + yc +")"; + const dist = rn(Math.hypot(x0 - x, y0 - y)); + const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + const atan = x0 > x ? Math.atan2(y0 - y, x0 - x) : Math.atan2(y - y0, x - x0); + const angle = rn(atan * 180 / Math.PI, 3); + const tr = "rotate(" + angle + " " + xc + " " + yc + ")"; group.select("text").attr("x", xc).attr("y", yc).attr("transform", tr).attr("data-dist", dist).text(label); } // draw ruler center point to split ruler into 2 parts function rulerCenterDrag() { - var xc1, yc1, xc2, yc2; - var group = d3.select(this.parentNode); // current ruler group - var x = d3.event.x, y = d3.event.y; // current coords - var line = group.selectAll("line"); // current lines - var x1 = +line.attr("x1"), y1 = +line.attr("y1"), x2 = +line.attr("x2"), y2 = +line.attr("y2"); // initial line edge points - var rulerNew = ruler.insert("g", ":first-child"); + let xc1, yc1, xc2, yc2; + const group = d3.select(this.parentNode); // current ruler group + let x = d3.event.x, y = d3.event.y; // current coords + const line = group.selectAll("line"); // current lines + const x1 = +line.attr("x1"), y1 = +line.attr("y1"), x2 = +line.attr("x2"), y2 = +line.attr("y2"); // initial line edge points + const rulerNew = ruler.insert("g", ":first-child"); rulerNew.attr("transform", group.attr("transform")).call(d3.drag().on("start", elementDrag)); - var factor = rn(1 / Math.pow(scale, 0.3), 1); + const factor = rn(1 / Math.pow(scale, 0.3), 1); rulerNew.append("line").attr("class", "white").attr("stroke-width", factor); - var dash = +group.select(".gray").attr("stroke-dasharray"); + const dash = +group.select(".gray").attr("stroke-dasharray"); rulerNew.append("line").attr("class", "gray").attr("stroke-dasharray", dash).attr("stroke-width", factor); rulerNew.append("text").attr("dy", -1).on("click", removeParent).attr("font-size", 10 * factor).attr("stroke-width", factor); @@ -1766,11 +1808,11 @@ function fantasyMap() { d3.select(this).attr("cx", x).attr("cy", y); // change first part line.attr("x1", x1).attr("y1", y1).attr("x2", x).attr("y2", y); - var dist = rn(Math.hypot(x1 - x, y1 - y)); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; - var atan = x1 > x ? Math.atan2(y1 - y, x1 - x) : Math.atan2(y - y1, x - x1); + let dist = rn(Math.hypot(x1 - x, y1 - y)); + let label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + let atan = x1 > x ? Math.atan2(y1 - y, x1 - x) : Math.atan2(y - y1, x - x1); xc1 = rn((x + x1) / 2, 2), yc1 = rn((y + y1) / 2, 2); - var tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc1 + " " + yc1 +")"; + let tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc1 + " " + yc1 + ")"; group.select("text").attr("x", xc1).attr("y", yc1).attr("transform", tr).attr("data-dist", dist).text(label); // change second (new) part dist = rn(Math.hypot(x2 - x, y2 - y)); @@ -1796,38 +1838,38 @@ function fantasyMap() { } function opisometerEdgeDrag() { - var el = d3.select(this); - var x0 = +el.attr("cx"), y0 = +el.attr("cy"); - var group = d3.select(this.parentNode); - var curve = group.select(".white"); - var curveGray = group.select(".gray"); - var text = group.select("text"); - var points = JSON.parse(text.attr("data-points")); + const el = d3.select(this); + const x0 = +el.attr("cx"), y0 = +el.attr("cy"); + const group = d3.select(this.parentNode); + const curve = group.select(".white"); + const curveGray = group.select(".gray"); + const text = group.select("text"); + const points = JSON.parse(text.attr("data-points")); if (x0 === points[0].scX && y0 === points[0].scY) {points.reverse();} d3.event.on("drag", function() { - var x = d3.event.x, y = d3.event.y; + const x = d3.event.x, y = d3.event.y; el.attr("cx", x).attr("cy", y); - var l = points[points.length - 1]; - var diff = Math.hypot(l.scX - x, l.scY - y); + const l = points[points.length - 1]; + const diff = Math.hypot(l.scX - x, l.scY - y); if (diff > 5) {points.push({scX: x, scY: y});} else {return;} lineGen.curve(d3.curveBasis); - var d = round(lineGen(points)); + const d = round(lineGen(points)); curve.attr("d", d); curveGray.attr("d", d); - var dist = rn(curve.node().getTotalLength()); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + const dist = rn(curve.node().getTotalLength()); + const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; text.attr("x", x).attr("y", y).text(label); }); d3.event.on("end", function() { - var dist = rn(curve.node().getTotalLength()); - var c = curve.node().getPointAtLength(dist / 2); - var p = curve.node().getPointAtLength((dist / 2) - 1); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; - var atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); - var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + c.x + " " + c.y +")"; + const dist = rn(curve.node().getTotalLength()); + const c = curve.node().getPointAtLength(dist / 2); + const p = curve.node().getPointAtLength((dist / 2) - 1); + const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + const atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); + const angle = rn(atan * 180 / Math.PI, 3); + const tr = "rotate(" + angle + " " + c.x + " " + c.y + ")"; text.attr("data-points", JSON.stringify(points)).attr("data-dist", dist).attr("x", c.x).attr("y", c.y).attr("transform", tr).text(label); }); } @@ -2007,11 +2049,15 @@ function fantasyMap() { if (cells[min].river == undefined) { cells[min].river = land[i].river; } else { - var riverTo = cells[min].river; - var iRiver = $.grep(riversData, function(e) {return (e.river == land[i].river);}); - var minRiver = $.grep(riversData, function(e) {return (e.river == riverTo);}); - var iRiverL = iRiver.length; - var minRiverL = minRiver.length; + const riverTo = cells[min].river; + const iRiver = $.grep(riversData, function (e) { + return (e.river == land[i].river); + }); + const minRiver = $.grep(riversData, function (e) { + return (e.river == riverTo); + }); + let iRiverL = iRiver.length; + let minRiverL = minRiver.length; // re-assing river nunber if new part is greater if (iRiverL >= minRiverL) { cells[min].river = land[i].river; @@ -2054,12 +2100,14 @@ function fantasyMap() { function drawRiverLines(riverNext) { console.time('drawRiverLines'); for (let i = 0; i < riverNext; i++) { - var dataRiver = $.grep(riversData, function(e) {return e.river === i;}); + const dataRiver = $.grep(riversData, function (e) { + return e.river === i; + }); if (dataRiver.length > 1) { - var riverAmended = amendRiver(dataRiver, 1); - var width = rn(0.8 + Math.random() * 0.4, 1); - var increment = rn(0.8 + Math.random() * 0.4, 1); - var d = drawRiver(riverAmended, width, increment); + const riverAmended = amendRiver(dataRiver, 1); + const width = rn(0.8 + Math.random() * 0.4, 1); + const increment = rn(0.8 + Math.random() * 0.4, 1); + const d = drawRiver(riverAmended, width, increment); rivers.append("path").attr("d", d).attr("id", "river"+i).attr("data-width", width).attr("data-increment", increment); } } @@ -2069,29 +2117,30 @@ function fantasyMap() { // add more river points on 1/3 and 2/3 of length function amendRiver(dataRiver, rndFactor) { - var riverAmended = [],side = 1; + const riverAmended = []; + let side = 1; for (let r = 0; r < dataRiver.length; r++) { - var dX = dataRiver[r].x; - var dY = dataRiver[r].y; - var cell = dataRiver[r].cell; - var c = cells[cell].confluence || 0; + const dX = dataRiver[r].x; + const dY = dataRiver[r].y; + const cell = dataRiver[r].cell; + const c = cells[cell].confluence || 0; riverAmended.push([dX, dY, c]); if (r+1 < dataRiver.length) { - var eX = dataRiver[r+1].x; - var eY = dataRiver[r+1].y; - var angle = Math.atan2(eY - dY, eX - dX); - var serpentine = 1 / (r+1); - var meandr = serpentine + 0.3 + Math.random() * 0.3 * rndFactor; + const eX = dataRiver[r + 1].x; + const eY = dataRiver[r + 1].y; + const angle = Math.atan2(eY - dY, eX - dX); + const serpentine = 1 / (r + 1); + const meandr = serpentine + 0.3 + Math.random() * 0.3 * rndFactor; if (Math.random() > 0.5) { side *= -1 } - var dist = Math.hypot(eX - dX, eY - dY); + const dist = Math.hypot(eX - dX, eY - dY); // if dist is big or river is small add 2 extra points if (dist > 8 || (dist > 4 && dataRiver.length < 6)) { - var stX = (dX * 2 + eX) / 3; - var stY = (dY * 2 + eY) / 3; - var enX = (dX + eX * 2) / 3; - var enY = (dY + eY * 2) / 3; + let stX = (dX * 2 + eX) / 3; + let stY = (dY * 2 + eY) / 3; + let enX = (dX + eX * 2) / 3; + let enY = (dY + eY * 2) / 3; stX += -Math.sin(angle) * meandr * side; stY += Math.cos(angle) * meandr * side; if (Math.random() > 0.8) { @@ -2102,8 +2151,8 @@ function fantasyMap() { riverAmended.push([stX, stY],[enX, enY]); // if dist is medium or river is small add 1 extra point } else if (dist > 4 || dataRiver.length < 6) { - var scX = (dX + eX) / 2; - var scY = (dY + eY) / 2; + let scX = (dX + eX) / 2; + let scY = (dY + eY) / 2; scX += -Math.sin(angle) * meandr * side; scY += Math.cos(angle) * meandr * side; riverAmended.push([scX, scY]); @@ -2116,33 +2165,33 @@ function fantasyMap() { // draw river polygon using arrpoximation function drawRiver(points, width, increment) { lineGen.curve(d3.curveCatmullRom.alpha(0.1)); - var extraOffset = 0.03; // start offset to make river source visible + let extraOffset = 0.03; // start offset to make river source visible width = width || 1; // river width modifier increment = increment || 1; // river bed widening modifier - var riverLength = 0; - points.map(function(p, i) { + let riverLength = 0; + points.map(function(p, i) { if (i === 0) {return 0;} riverLength += Math.hypot(p[0] - points[i-1][0],p[1] - points[i-1][1]); }); - var widening = rn((1000 + (riverLength * 30)) * increment); - var riverPointsLeft = [],riverPointsRight = []; - var last = points.length - 1; - var factor = riverLength / points.length; + const widening = rn((1000 + (riverLength * 30)) * increment); + const riverPointsLeft = [], riverPointsRight = []; + const last = points.length - 1; + const factor = riverLength / points.length; - // first point - var x = points[0][0],y = points[0][1],c; - var angle = Math.atan2(y - points[1][1],x - points[1][0]); - var xLeft = x + -Math.sin(angle) * extraOffset, yLeft = y + Math.cos(angle) * extraOffset; - riverPointsLeft.push({scX:xLeft, scY:yLeft}); - var xRight = x + Math.sin(angle) * extraOffset, yRight = y + -Math.cos(angle) * extraOffset; - riverPointsRight.unshift({scX:xRight, scY:yRight}); + // first point + let x = points[0][0], y = points[0][1], c; + let angle = Math.atan2(y - points[1][1], x - points[1][0]); + let xLeft = x + -Math.sin(angle) * extraOffset, yLeft = y + Math.cos(angle) * extraOffset; + riverPointsLeft.push({scX:xLeft, scY:yLeft}); + let xRight = x + Math.sin(angle) * extraOffset, yRight = y + -Math.cos(angle) * extraOffset; + riverPointsRight.unshift({scX:xRight, scY:yRight}); // middle points for (let p = 1; p < last; p ++) { x = points[p][0],y = points[p][1],c = points[p][2]; if (c) {extraOffset += Math.atan(c * 10 / widening);} // confluence - var xPrev = points[p-1][0],yPrev = points[p-1][1]; - var xNext = points[p+1][0],yNext = points[p+1][1]; + const xPrev = points[p - 1][0], yPrev = points[p - 1][1]; + const xNext = points[p + 1][0], yNext = points[p + 1][1]; angle = Math.atan2(yPrev - yNext, xPrev - xNext); var offset = (Math.atan(Math.pow(p * factor, 2) / widening) / 2 * width) + extraOffset; xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; @@ -2161,9 +2210,9 @@ function fantasyMap() { riverPointsRight.unshift({scX:xRight, scY:yRight}); // generate path and return - var right = lineGen(riverPointsRight); - var left = lineGen(riverPointsLeft); - left = left.substring(left.indexOf("C")); + const right = lineGen(riverPointsRight); + let left = lineGen(riverPointsLeft); + left = left.substring(left.indexOf("C")); return round(right + left, 2); } @@ -2171,18 +2220,20 @@ function fantasyMap() { function drawRiverSlow(points, width, increment) { lineGen.curve(d3.curveCatmullRom.alpha(0.1)); width = width || 1; - var extraOffset = 0.02 * width; - increment = increment || 1; - var riverPoints = points.map(function(p) {return {scX: p[0],scY: p[1]};}); - var river = defs.append("path").attr("d", lineGen(riverPoints)); - var riverLength = river.node().getTotalLength(); - var widening = rn((1000 + (riverLength * 30)) * increment); - var riverPointsLeft = [],riverPointsRight = []; + const extraOffset = 0.02 * width; + increment = increment || 1; + const riverPoints = points.map(function (p) { + return {scX: p[0], scY: p[1]}; + }); + const river = defs.append("path").attr("d", lineGen(riverPoints)); + const riverLength = river.node().getTotalLength(); + const widening = rn((1000 + (riverLength * 30)) * increment); + const riverPointsLeft = [], riverPointsRight = []; - for (let l = 0; l < riverLength; l++) { + for (let l = 0; l < riverLength; l++) { var point = river.node().getPointAtLength(l); var from = river.node().getPointAtLength(l - 0.1); - var to = river.node().getPointAtLength(l + 0.1); + const to = river.node().getPointAtLength(l + 0.1); var angle = Math.atan2(from.y - to.y, from.x - to.x); var offset = (Math.atan(Math.pow(l, 2) / widening) / 2 * width) + extraOffset; var xLeft = point.x + -Math.sin(angle) * offset; @@ -2206,9 +2257,9 @@ function fantasyMap() { river.remove(); // generate path and return - var right = lineGen(riverPointsRight); - var left = lineGen(riverPointsLeft); - left = left.substring(left.indexOf("C")); + const right = lineGen(riverPointsRight); + let left = lineGen(riverPointsLeft); + left = left.substring(left.indexOf("C")); return round(right + left, 2); } @@ -2788,7 +2839,7 @@ function fantasyMap() { $("#riverAngle").on("input", function() { const tr = parseTransform(elSelected.attr("transform")); riverAngleValue.innerHTML = Math.abs(+this.value) + "°"; - var c = elSelected.node().getBBox(); + const c = elSelected.node().getBBox(); const angle = +this.value, scale = +tr[5]; const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x+c.width/2)*scale} ${(c.y+c.height/2)*scale}) scale(${scale})`; elSelected.attr("transform", transform); @@ -2806,7 +2857,7 @@ function fantasyMap() { $("#riverScale").change(function() { const tr = parseTransform(elSelected.attr("transform")); const scaleOld = +tr[5],scale = +this.value; - var c = elSelected.node().getBBox(); + const c = elSelected.node().getBBox(); const cx = c.x + c.width / 2, cy = c.y + c.height / 2; const trX = +tr[0] + cx * (scaleOld - scale); const trY = +tr[1] + cy * (scaleOld - scale); @@ -3020,7 +3071,7 @@ function fantasyMap() { function routeRedraw() { let points = []; debug.select(".controlPoints").selectAll("circle").each(function() { - var el = d3.select(this); + const el = d3.select(this); points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); }); lineGen.curve(d3.curveCatmullRom.alpha(0.1)); @@ -3448,7 +3499,7 @@ function fantasyMap() { function updateBurgsGroupOptions() { burgSelectGroup.innerHTML = ""; burgIcons.selectAll("g").each(function(d) { - var opt = document.createElement("option"); + const opt = document.createElement("option"); opt.value = opt.innerHTML = d3.select(this).attr("id"); burgSelectGroup.add(opt); }); @@ -3522,7 +3573,7 @@ function fantasyMap() { const group = d3.select(elSelected.node().parentNode); const type = group.attr("id"); const id = +elSelected.attr("data-id"); - var count = group.selectAll("*").size(); + const count = group.selectAll("*").size(); const message = "Are you sure you want to remove all Burgs (" + count + ") of that group?"; alertMessage.innerHTML = message; $("#alert").dialog({resizable: false, title: "Remove Burgs", @@ -4280,7 +4331,7 @@ function fantasyMap() { // transform string to array [translateX,translateY,rotateDeg,rotateX,rotateY,scale] function parseTransform(string) { if (!string) {return [0,0,0,0,0,1];} - var a = string.replace(/[a-z()]/g,"").replace(/[ ]/g,",").split(","); + const a = string.replace(/[a-z()]/g, "").replace(/[ ]/g, ",").split(","); return [a[0] || 0, a[1] || 0, a[2] || 0, a[3] || 0, a[4] || 0, a[5] || 1]; } @@ -4373,11 +4424,11 @@ function fantasyMap() { function rankPlacesEconomy() { console.time('rankPlacesEconomy'); land.map(function(c) { - var score = c.score; - var path = c.path || 0; // roads are valued + let score = c.score; + let path = c.path || 0; // roads are valued if (path) { path = Math.pow(path, 0.2); - var crossroad = c.crossroad || 0; // crossroads are valued + const crossroad = c.crossroad || 0; // crossroads are valued score = score + path + crossroad; } c.score = rn(Math.random() * score + score, 2); // add random factor @@ -4393,8 +4444,8 @@ function fantasyMap() { // calculate population for each burg (based on trade/people attractors) manors.map(function(m) { - var cell = cells[m.cell]; - var score = cell.score; + const cell = cells[m.cell]; + let score = cell.score; if (score <= 0) {score = rn(Math.random(), 2)} if (cell.crossroad) {score += cell.crossroad;} // crossroads if (cell.confluence) {score += Math.pow(cell.confluence, 0.3);} // confluences @@ -4419,13 +4470,17 @@ function fantasyMap() { // calculate population for each region states.map(function(s, i) { // define region burgs count - var burgs = $.grep(manors, function(e) {return e.region === i;}); + const burgs = $.grep(manors, function (e) { + return e.region === i; + }); s.burgs = burgs.length; // define region total and burgs population - var burgsPop = 0; // get summ of all burgs population + let burgsPop = 0; // get summ of all burgs population burgs.map(function(b) {burgsPop += b.population;}); s.urbanPopulation = rn(burgsPop, 2); - var regionCells = $.grep(cells, function(e) {return e.region === i;}); + const regionCells = $.grep(cells, function (e) { + return e.region === i; + }); let cellsPop = 0; regionCells.map(function(c) {cellsPop += c.pop}); s.cells = regionCells.length; @@ -4568,21 +4623,27 @@ function fantasyMap() { console.time("checkAccessibility"); for (let f = 0; f < features.length; f++) { if (!features[f].land) continue; - var manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); + const manorsOnIsland = $.grep(land, function (e) { + return e.manor !== undefined && e.fn === f; + }); if (!manorsOnIsland.length) continue; // if lake port is the only port on lake, remove port - var lakePorts = $.grep(manorsOnIsland, function(p) {return p.port && !features[p.port].border;}); + const lakePorts = $.grep(manorsOnIsland, function (p) { + return p.port && !features[p.port].border; + }); if (lakePorts.length) { - var lakes = []; + const lakes = []; lakePorts.forEach(function(p) {lakes[p.port] = lakes[p.port] ? lakes[p.port] + 1 : 1;}); lakePorts.forEach(function(p) {if (lakes[p.port] === 1) p.port = undefined;}); } // check how many ocean ports are there on island - var oceanPorts = $.grep(manorsOnIsland, function(p) {return p.port && features[p.port].border;}); + const oceanPorts = $.grep(manorsOnIsland, function (p) { + return p.port && features[p.port].border; + }); if (oceanPorts.length) continue; - var portCandidates = $.grep(manorsOnIsland, function(c) { + const portCandidates = $.grep(manorsOnIsland, function (c) { return c.harbor && features[cells[c.harbor].fn].border && c.ctype === 1; }); if (portCandidates.length) { @@ -4652,10 +4713,12 @@ function fantasyMap() { console.time("generateSmallRoads"); if (manors.length < 2) return; for (let f = 0; f < features.length; f++) { - var manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); - var l = manorsOnIsland.length; + const manorsOnIsland = $.grep(land, function (e) { + return e.manor !== undefined && e.fn === f; + }); + const l = manorsOnIsland.length; if (l > 1) { - var secondary = rn((l + 8) / 10); + const secondary = rn((l + 8) / 10); for (let s = 0; s < secondary; s++) { var start = manorsOnIsland[Math.floor(Math.random() * l)].index; var end = manorsOnIsland[Math.floor(Math.random() * l)].index; @@ -4667,18 +4730,21 @@ function fantasyMap() { } manorsOnIsland.map(function(e, d) { if (!e.path && d > 0) { - var start = e.index, end = -1; - var road = $.grep(land, function(e) {return e.path && e.fn === f;}); + const start = e.index; + let end = -1; + const road = $.grep(land, function (e) { + return e.path && e.fn === f; + }); if (road.length > 0) { - var minDist = 10000; + let minDist = 10000; road.map(function(i) { - var dist = Math.hypot(e.data[0] - i.data[0],e.data[1] - i.data[1]); + const dist = Math.hypot(e.data[0] - i.data[0], e.data[1] - i.data[1]); if (dist < minDist) {minDist = dist; end = i.index;} }); } else { end = manorsOnIsland[0].index; } - var path = findLandPath(start, end, "main"); + const path = findLandPath(start, end, "main"); restorePath(end, start, "small", path); } }); @@ -4772,18 +4838,22 @@ function fantasyMap() { function findLandPath(start, end, type) { // A* algorithm - var queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); - var cameFrom = []; - var costTotal = []; + const queue = new PriorityQueue({ + comparator: function (a, b) { + return a.p - b.p + } + }); + const cameFrom = []; + const costTotal = []; costTotal[start] = 0; queue.queue({e: start, p: 0}); while (queue.length > 0) { - var next = queue.dequeue().e; + const next = queue.dequeue().e; if (next === end) {break;} - var pol = cells[next]; + const pol = cells[next]; pol.neighbors.forEach(function(e) { if (cells[e].height >= 20) { - var cost = cells[e].height / 100 * 2; + let cost = cells[e].height / 100 * 2; if (cells[e].path && type === "main") { cost = 0.15; } else { @@ -4793,12 +4863,12 @@ function fantasyMap() { if (cells[e].path) {cost *= 0.5;} cost += Math.hypot(cells[e].data[0] - pol.data[0],cells[e].data[1] - pol.data[1]) / 30; } - var costNew = costTotal[next] + cost; + const costNew = costTotal[next] + cost; if (!cameFrom[e] || costNew < costTotal[e]) { // costTotal[e] = costNew; cameFrom[e] = next; - var dist = Math.hypot(cells[e].data[0] - cells[end].data[0],cells[e].data[1] - cells[end].data[1]) / 15; - var priority = costNew + dist; + const dist = Math.hypot(cells[e].data[0] - cells[end].data[0], cells[e].data[1] - cells[end].data[1]) / 15; + const priority = costNew + dist; queue.queue({e, p: priority}); } } @@ -4866,19 +4936,23 @@ function fantasyMap() { } function getPathDist(start, end) { - var queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); - var next, costNew; - var cameFrom = []; - var costTotal = []; + const queue = new PriorityQueue({ + comparator: function (a, b) { + return a.p - b.p + } + }); + let next, costNew; + const cameFrom = []; + const costTotal = []; cameFrom[start] = "no"; costTotal[start] = 0; queue.queue({e: start, p: 0}); while (queue.length > 0 && next !== end) { next = queue.dequeue().e; - var pol = cells[next]; + const pol = cells[next]; pol.neighbors.forEach(function(e) { if (cells[e].path && (cells[e].ctype === -1 || cells[e].haven === next)) { - var dist = Math.hypot(cells[e].data[0] - pol.data[0],cells[e].data[1] - pol.data[1]); + const dist = Math.hypot(cells[e].data[0] - pol.data[0], cells[e].data[1] - pol.data[1]); costNew = costTotal[next] + dist; if (!cameFrom[e]) { costTotal[e] = costNew; @@ -4892,13 +4966,14 @@ function fantasyMap() { } function restorePath(end, start, type, from) { - var path = [],current = end, limit = 1000; - var prev = cells[end]; + let path = [], current = end; + const limit = 1000; + let prev = cells[end]; if (type === "ocean" || !prev.path) {path.push({scX: prev.data[0],scY: prev.data[1],i: end});} if (!prev.path) {prev.path = 1;} for (let i = 0; i < limit; i++) { current = from[current]; - var cur = cells[current]; + let cur = cells[current]; if (!cur) {break;} if (cur.path) { cur.path += 1; @@ -4918,20 +4993,20 @@ function fantasyMap() { if (path.length > 1) { // mark crossroades if (type === "main" || type === "small") { - var plus = type === "main" ? 4 : 2; - var f = cells[path[0].i]; + const plus = type === "main" ? 4 : 2; + const f = cells[path[0].i]; if (f.path > 1) { if (!f.crossroad) {f.crossroad = 0;} f.crossroad += plus; } - var t = cells[(path[path.length - 1].i)]; + const t = cells[(path[path.length - 1].i)]; if (t.path > 1) { if (!t.crossroad) {t.crossroad = 0;} t.crossroad += plus; } } // draw path segments - var line = lineGen(path); + let line = lineGen(path); line = round(line, 1); let id = 0; // to create unique route id if (type === "main") { @@ -5243,19 +5318,22 @@ function fantasyMap() { } function drawRegion(edges, region) { - var path = "", array = []; + let path = ""; + const array = []; lineGen.curve(d3.curveLinear); while (edges.length > 2) { - var edgesOrdered = []; // to store points in a correct order - var start = edges[0].start; - var end = edges[0].end; + const edgesOrdered = []; // to store points in a correct order + const start = edges[0].start; + let end = edges[0].end; edges.shift(); - var spl = start.split(" "); + let spl = start.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); spl = end.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); for (let i = 0; end !== start && i < 2000; i++) { - var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + const next = $.grep(edges, function (e) { + return (e.start == end || e.end == end); + }); if (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -5265,13 +5343,13 @@ function fantasyMap() { spl = end.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); } - var rem = edges.indexOf(next[0]); + const rem = edges.indexOf(next[0]); edges.splice(rem, 1); } path += lineGen(edgesOrdered) + "Z "; array[array.length] = edgesOrdered.map(function(e) {return [+e.scX, +e.scY];}); } - var color = states[region].color; + const color = states[region].color; regions.append("path").attr("d", round(path, 1)).attr("fill", color).attr("class", "region"+region); array.sort(function(a, b){return b.length - a.length;}); let capital = states[region].capital; @@ -5280,24 +5358,26 @@ function fantasyMap() { const capitalCell = manors[capital].cell; array.push(polygons[capitalCell]); } - var name = states[region].name; - var c = polylabel(array, 1.0); // pole of inaccessibility + const name = states[region].name; + const c = polylabel(array, 1.0); // pole of inaccessibility labels.select("#countries").append("text").attr("id", "regionLabel"+region).attr("x", rn(c[0])).attr("y", rn(c[1])).text(name).on("click", editLabel); states[region].area = rn(Math.abs(d3.polygonArea(array[0]))); // define region area } function drawRegionCoast(edges, region) { - var path = ""; + let path = ""; while (edges.length > 0) { - var edgesOrdered = []; // to store points in a correct order - var start = edges[0].start; - var end = edges[0].end; + const edgesOrdered = []; // to store points in a correct order + const start = edges[0].start; + let end = edges[0].end; edges.shift(); - var spl = start.split(" "); + let spl = start.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); spl = end.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); - var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + let next = $.grep(edges, function (e) { + return (e.start == end || e.end == end); + }); while (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -5306,29 +5386,31 @@ function fantasyMap() { } spl = end.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); - var rem = edges.indexOf(next[0]); + const rem = edges.indexOf(next[0]); edges.splice(rem, 1); next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); } path += lineGen(edgesOrdered); } - var color = states[region].color; + const color = states[region].color; regions.append("path").attr("d", round(path, 1)).attr("fill", "none").attr("stroke", color).attr("stroke-width", 5).attr("class", "region"+region); } function drawBorders(edges, type) { - var path = ""; + let path = ""; if (edges.length < 1) {return;} while (edges.length > 0) { - var edgesOrdered = []; // to store points in a correct order - var start = edges[0].start; - var end = edges[0].end; + const edgesOrdered = []; // to store points in a correct order + const start = edges[0].start; + let end = edges[0].end; edges.shift(); - var spl = start.split(" "); + let spl = start.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); spl = end.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); - var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + let next = $.grep(edges, function (e) { + return (e.start == end || e.end == end); + }); while (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -5337,7 +5419,7 @@ function fantasyMap() { } spl = end.split(" "); edgesOrdered.push({scX: spl[0],scY: spl[1]}); - var rem = edges.indexOf(next[0]); + const rem = edges.indexOf(next[0]); edges.splice(rem, 1); next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); } @@ -5626,16 +5708,16 @@ function fantasyMap() { // draw Overlay function toggleOverlay() { if (overlay.selectAll("*").size() === 0) { - var type = styleOverlayType.value; - var size = +styleOverlaySize.value; + const type = styleOverlayType.value; + const size = +styleOverlaySize.value; if (type === "pointyHex" || type === "flatHex") { let points = getHexGridPoints(size, type); let hex = "m" + getHex(size, type).slice(0, 4).join("l"); let d = points.map(function(p) {return "M" + p + hex;}).join(""); overlay.append("path").attr("d", d); } else if (type === "square") { - var x = d3.range(size, svgWidth, size); - var y = d3.range(size, svgHeight, size); + const x = d3.range(size, svgWidth, size); + const y = d3.range(size, svgHeight, size); overlay.append("g").selectAll("line").data(x).enter().append("line") .attr("x1", function(d) {return d;}) .attr("x2", function(d) {return d;}) @@ -5645,7 +5727,7 @@ function fantasyMap() { .attr("y2", function(d) {return d;}) .attr("x1", 0).attr("x2", svgWidth); } else { - var tr = `translate(80 80) scale(${size / 20})`; + const tr = `translate(80 80) scale(${size / 20})`; d3.select("#rose").attr("transform", tr); overlay.append("use").attr("xlink:href","#rose"); } @@ -5662,10 +5744,10 @@ function fantasyMap() { let thirdPi = Math.PI / 3; let angles = [s, s + thirdPi, s + 2 * thirdPi, s + 3 * thirdPi, s + 4 * thirdPi, s + 5 * thirdPi]; return angles.map(function(angle) { - var x1 = Math.sin(angle) * radius, - y1 = -Math.cos(angle) * radius, - dx = x1 - x0, - dy = y1 - y0; + const x1 = Math.sin(angle) * radius, + y1 = -Math.cos(angle) * radius, + dx = x1 - x0, + dy = y1 - y0; x0 = x1, y0 = y1; return [dx, dy]; }); @@ -5726,7 +5808,7 @@ function fantasyMap() { // Draw the water flux system (for dubugging) function toggleFlux() { - var colorFlux = d3.scaleSequential(d3.interpolateBlues); + const colorFlux = d3.scaleSequential(d3.interpolateBlues); if (terrs.selectAll("path").size() == 0) { land.map(function(i) { terrs.append("path") @@ -5901,7 +5983,8 @@ function fantasyMap() { } function drawSwamp(x, y) { - var h = 0.6, line = ""; + const h = 0.6; + let line = ""; for (let c = 0; c < 3; c++) { let cx; let cy; @@ -5924,17 +6007,17 @@ function fantasyMap() { } function dragged(e) { - var el = d3.select(this); - var x = d3.event.x; - var y = d3.event.y; + const el = d3.select(this); + const x = d3.event.x; + const y = d3.event.y; el.raise().classed("drag", true); if (el.attr("x")) { el.attr("x", x).attr("y", y + 0.8); - var matrix = el.attr("transform"); + const matrix = el.attr("transform"); if (matrix) { - var angle = matrix.split('(')[1].split(')')[0].split(' ')[0]; - var bbox = el.node().getBBox(); - var rotate = "rotate("+ angle + " " + (bbox.x + bbox.width/2) + " " + (bbox.y + bbox.height/2) + ")"; + const angle = matrix.split('(')[1].split(')')[0].split(' ')[0]; + const bbox = el.node().getBBox(); + const rotate = "rotate(" + angle + " " + (bbox.x + bbox.width / 2) + " " + (bbox.y + bbox.height / 2) + ")"; el.attr("transform", rotate); } } else { @@ -6060,7 +6143,7 @@ function fantasyMap() { d3.select("#toggleGrid").classed("buttonoff", false); return; } - var i = manors.length; + const i = manors.length; const size = burgIcons.select("#towns").attr("size"); burgIcons.select("#towns").append("circle").attr("id", "burg"+i).attr("data-id", i).attr("cx", x).attr("cy", y).attr("r", size).on("click", editBurg); burgLabels.select("#towns").append("text").attr("data-id", i).attr("x", x).attr("y", y).attr("dy", "-0.35em").text(name).on("click", editBurg); @@ -6071,10 +6154,10 @@ function fantasyMap() { restoreDefaultEvents(); } - var region, state = +$("#addBurg").attr("data-state"); + let region, state = +$("#addBurg").attr("data-state"); if (state !== -1) { region = states[state].capital === "neutral" ? "neutral" : state; - var oldRegion = cells[index].region; + const oldRegion = cells[index].region; if (region !== oldRegion) { cells[index].region = region; redrawRegions(); @@ -6089,7 +6172,7 @@ function fantasyMap() { if (cells[index].crossroad) {score += cells[index].crossroad;} // crossroads if (cells[index].confluence) {score += Math.pow(cells[index].confluence, 0.3);} // confluences if (cells[index].port !== undefined) {score *= 3;} // port-capital - var population = rn(score, 1); + const population = rn(score, 1); manors.push({i, cell:index, x, y, region, culture, name, population}); recalculateStateData(state); updateCountryEditors(); @@ -6114,26 +6197,26 @@ function fantasyMap() { }); function addRiverOnClick() { - var point = d3.mouse(this); - var index = diagram.find(point[0],point[1]).index; - var cell = cells[index]; + const point = d3.mouse(this); + const index = diagram.find(point[0], point[1]).index; + let cell = cells[index]; if (cell.river || cell.height < 20) return; - var dataRiver = []; // to store river points + const dataRiver = []; // to store river points const last = $("#rivers > path").last(); const river = last.length ? +last.attr("id").slice(5) + 1 : 0; cell.flux = 0.85; while (cell) { cell.river = river; - var x = cell.data[0],y = cell.data[1]; + const x = cell.data[0], y = cell.data[1]; dataRiver.push({x, y, cell:index}); - var nHeights = []; + const nHeights = []; cell.neighbors.forEach(function(e) {nHeights.push(cells[e].height);}); - var minId = nHeights.indexOf(d3.min(nHeights)); - var min = cell.neighbors[minId]; - var tx = cells[min].data[0],ty = cells[min].data[1]; + const minId = nHeights.indexOf(d3.min(nHeights)); + const min = cell.neighbors[minId]; + const tx = cells[min].data[0], ty = cells[min].data[1]; if (cells[min].height < 20) { - var px = (x + tx) / 2; - var py = (y + ty) / 2; + const px = (x + tx) / 2; + const py = (y + ty) / 2; dataRiver.push({x: px, y: py, cell:index}); cell = undefined; } else { @@ -6179,7 +6262,7 @@ function fantasyMap() { } } } - var rndFactor = 0.2 + Math.random() * 1.6; // random factor in range 0.2-1.8 + const rndFactor = 0.2 + Math.random() * 1.6; // random factor in range 0.2-1.8 var riverAmended = amendRiver(dataRiver, rndFactor); var d = drawRiver(riverAmended, 1.3, 1); rivers.append("path").attr("d", d).attr("id", "river"+river) @@ -6427,8 +6510,8 @@ function fantasyMap() { // round value to d decimals function rn(v, d) { var d = d || 0; - var m = Math.pow(10, d); - return Math.round(v * m) / m; + const m = Math.pow(10, d); + return Math.round(v * m) / m; } // round string to d decimals @@ -6449,7 +6532,7 @@ function fantasyMap() { // getInteger number from user input data function getInteger(value) { - var metric = value.slice(-1); + const metric = value.slice(-1); if (metric === "K") {return parseInt(value.slice(0, -1) * 1e3);} if (metric === "M") {return parseInt(value.slice(0, -1) * 1e6);} if (metric === "B") {return parseInt(value.slice(0, -1) * 1e9);} @@ -6471,10 +6554,10 @@ function fantasyMap() { const fontsToLoad = "https://fonts.googleapis.com/css?family=" + fontsInUse.join("|"); // clone svg - var cloneEl = document.getElementsByTagName("svg")[0].cloneNode(true); + const cloneEl = document.getElementsByTagName("svg")[0].cloneNode(true); cloneEl.id = "fantasyMap"; document.getElementsByTagName("body")[0].appendChild(cloneEl); - var clone = d3.select("#fantasyMap"); + const clone = d3.select("#fantasyMap"); // rteset transform for svg if (type === "svg") { @@ -6543,17 +6626,17 @@ function fantasyMap() { // load fonts as dataURI so they will be available in downloaded svg/png GFontToDataURI(fontsToLoad).then(cssRules => { clone.select("defs").append("style").text(cssRules.join('\n')); - var svg_xml = (new XMLSerializer()).serializeToString(clone.node()); + const svg_xml = (new XMLSerializer()).serializeToString(clone.node()); clone.remove(); - var blob = new Blob([svg_xml],{type:'image/svg+xml;charset=utf-8'}); - var url = window.URL.createObjectURL(blob); - var link = document.createElement("a"); + const blob = new Blob([svg_xml], {type: 'image/svg+xml;charset=utf-8'}); + const url = window.URL.createObjectURL(blob); + const link = document.createElement("a"); link.target = "_blank"; if (type === "png") { - var ratio = svgHeight / svgWidth; + const ratio = svgHeight / svgWidth; canvas.width = svgWidth * pngResolutionInput.value; canvas.height = svgHeight * pngResolutionInput.value; - var img = new Image(); + const img = new Image(); img.src = url; img.onload = function(){ window.URL.revokeObjectURL(url); @@ -6652,14 +6735,14 @@ function fantasyMap() { const oceanShift = [oceanBack.attr("x"), oceanBack.attr("y"), oceanBack.attr("width"), oceanBack.attr("height")]; oceanBack.attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight); - var svg_xml = (new XMLSerializer()).serializeToString(svg.node()); - var line = "\r\n"; - var data = params + line + JSON.stringify(points) + line + JSON.stringify(cells) + line; + const svg_xml = (new XMLSerializer()).serializeToString(svg.node()); + const line = "\r\n"; + let data = params + line + JSON.stringify(points) + line + JSON.stringify(cells) + line; data += JSON.stringify(manors) + line + JSON.stringify(states) + line + svg_xml + line + options + line; data += JSON.stringify(cultures) + line + "" + line + "" + line + heights + line + JSON.stringify(notes) + line; - var dataBlob = new Blob([data],{type:"text/plain"}); - var dataURL = window.URL.createObjectURL(dataBlob); - var link = document.createElement("a"); + const dataBlob = new Blob([data], {type: "text/plain"}); + const dataURL = window.URL.createObjectURL(dataBlob); + const link = document.createElement("a"); link.download = "fantasy_map_" + Date.now() + ".map"; link.href = dataURL; document.body.appendChild(link); @@ -6678,23 +6761,23 @@ function fantasyMap() { $("#mapToLoad").change(function() { console.time("loadMap"); closeDialogs(); - var fileToLoad = this.files[0]; + const fileToLoad = this.files[0]; this.value = ""; uploadFile(fileToLoad); }); function uploadFile(file, callback) { console.time("loadMap"); - var fileReader = new FileReader(); + const fileReader = new FileReader(); fileReader.onload = function(fileLoadedEvent) { - var dataLoaded = fileLoadedEvent.target.result; - var data = dataLoaded.split("\r\n"); + const dataLoaded = fileLoadedEvent.target.result; + const data = dataLoaded.split("\r\n"); // data convention: 0 - params; 1 - all points; 2 - cells; 3 - manors; 4 - states; // 5 - svg; 6 - options; 7 - cultures; 8 - none; 9 - none; 10 - heights; 11 - notes; const params = data[0].split("|"); const mapVersion = params[0] || data[0]; if (mapVersion !== version) { - var message = `The Map version `; + let message = `The Map version `; // mapVersion reference was not added to downloaded map before v. 0.52b, so I cannot support really old files if (mapVersion.length <= 10) { message += `(${mapVersion}) does not match the Generator version (${version}). The map will be auto-updated. @@ -7009,9 +7092,9 @@ function fantasyMap() { // update map to support some old versions and fetch fonts labels.selectAll("g").each(function(d) { - var el = d3.select(this); + const el = d3.select(this); if (el.attr("id") === "burgLabels") return; - var font = el.attr("data-font"); + const font = el.attr("data-font"); if (font && fonts.indexOf(font) === -1) addFonts("https://fonts.googleapis.com/css?family=" + font); if (!el.attr("data-size")) el.attr("data-size", +el.attr("font-size")); if (el.style("display") === "none") el.node().style.display = null; @@ -7117,10 +7200,10 @@ function fantasyMap() { // move layers on mapLayers dragging (jquery sortable) function moveLayer(event, ui) { - var el = getLayer(ui.item.attr("id")); + const el = getLayer(ui.item.attr("id")); if (el) { - var prev = getLayer(ui.item.prev().attr("id")); - var next = getLayer(ui.item.next().attr("id")); + const prev = getLayer(ui.item.prev().attr("id")); + const next = getLayer(ui.item.next().attr("id")); if (prev) {el.insertAfter(prev);} else if (next) {el.insertBefore(next);} } } @@ -7142,8 +7225,8 @@ function fantasyMap() { // UI Button handlers $("button, a, li, i").on("click", function() { - var id = this.id; - var parent = this.parentNode.id; + const id = this.id; + const parent = this.parentNode.id; if (debug.selectAll(".tag").size()) {debug.selectAll(".tag, .line").remove();} if (id === "toggleHeight") {toggleHeight();} if (id === "toggleCountries") {$('#regions').fadeToggle();} @@ -7193,14 +7276,14 @@ function fantasyMap() { } if (id === "countriesManuallyComplete") { debug.selectAll(".circle").remove(); - var changedCells = regions.select("#temp").selectAll("path"); - var changedStates = []; + const changedCells = regions.select("#temp").selectAll("path"); + let changedStates = []; changedCells.each(function() { - var el = d3.select(this); - var cell = +el.attr("data-cell"); - var stateOld = cells[cell].region; + const el = d3.select(this); + const cell = +el.attr("data-cell"); + let stateOld = cells[cell].region; if (stateOld === "neutral") {stateOld = states.length - 1;} - var stateNew = +el.attr("data-state"); + const stateNew = +el.attr("data-state"); const region = states[stateNew].color === "neutral" ? "neutral" : stateNew; cells[cell].region = region; if (cells[cell].manor !== undefined) {manors[cells[cell].manor].region = region;} @@ -7208,7 +7291,7 @@ function fantasyMap() { }); changedStates = [...new Set(changedStates)]; changedStates.map(function(s) {recalculateStateData(s);}); - var last = states.length - 1; + const last = states.length - 1; if (states[last].capital === "neutral" && states[last].cells === 0) { $("#state" + last).remove(); states.splice(-1); @@ -7244,11 +7327,11 @@ function fantasyMap() { regenerateCountries(); } if (id === "countriesAddM" || id === "countriesAddR" || id === "countriesAddG") { - var i = states.length; + let i = states.length; // move neutrals to the last line if (states[i-1].capital === "neutral") {states[i-1].i = i; i -= 1;} var name = generateStateName(0); - var color = colors20(i); + const color = colors20(i); states.push({i, color, name, capital: "select", cells: 0, burgs: 0, urbanPopulation: 0, ruralPopulation: 0, area: 0, power: 1}); states.sort(function(a, b){return a.i - b.i}); editCountries(); @@ -7266,16 +7349,16 @@ function fantasyMap() { var el = $("#countriesEditor"); if (el.attr("data-type") === "absolute") { el.attr("data-type", "percentage"); - var totalCells = land.length; - var totalBurgs = +countriesFooterBurgs.innerHTML; - var totalArea = countriesFooterArea.innerHTML; + const totalCells = land.length; + const totalBurgs = +countriesFooterBurgs.innerHTML; + let totalArea = countriesFooterArea.innerHTML; totalArea = getInteger(totalArea.split(" ")[0]); - var totalPopulation = getInteger(countriesFooterPopulation.innerHTML); + const totalPopulation = getInteger(countriesFooterPopulation.innerHTML); $("#countriesBody > .states").each(function() { - var cells = rn($(this).attr("data-cells") / totalCells * 100); - var burgs = rn($(this).attr("data-burgs") / totalBurgs * 100); - var area = rn($(this).attr("data-area") / totalArea * 100); - var population = rn($(this).attr("data-population") / totalPopulation * 100); + const cells = rn($(this).attr("data-cells") / totalCells * 100); + const burgs = rn($(this).attr("data-burgs") / totalBurgs * 100); + const area = rn($(this).attr("data-area") / totalArea * 100); + const population = rn($(this).attr("data-population") / totalPopulation * 100); $(this).children().filter(".stateCells").text(cells + "%"); $(this).children().filter(".stateBurgs").text(burgs + "%"); $(this).children().filter(".stateArea").text(area + "%"); @@ -7288,32 +7371,32 @@ function fantasyMap() { } if (id === "countriesExport") { if ($(".statePower").length === 0) {return;} - var unit = areaUnit.value === "square" ? distanceUnit.value + "2" : areaUnit.value; - var data = "Country,Capital,Cells,Burgs,Area ("+ unit +"),Population\n"; // countries headers + const unit = areaUnit.value === "square" ? distanceUnit.value + "2" : areaUnit.value; + let data = "Country,Capital,Cells,Burgs,Area (" + unit + "),Population\n"; // countries headers $("#countriesBody > .states").each(function() { - var country = $(this).attr("data-country"); + const country = $(this).attr("data-country"); if (country === "bottom") {data += "neutral,"} else {data += country + ",";} - var capital = $(this).attr("data-capital"); + const capital = $(this).attr("data-capital"); if (capital === "bottom" || capital === "select") {data += ","} else {data += capital + ",";} data += $(this).attr("data-cells") + ","; data += $(this).attr("data-burgs") + ","; data += $(this).attr("data-area") + ","; - var population = +$(this).attr("data-population"); + const population = +$(this).attr("data-population"); data += population + "\n"; }); data += "\nBurg,Country,Culture,Population\n"; // burgs headers manors.map(function(m) { if (m.region === "removed") return; // skip removed burgs data += m.name + ","; - var country = m.region === "neutral" ? "neutral" : states[m.region].name; + const country = m.region === "neutral" ? "neutral" : states[m.region].name; data += country + ","; data += cultures[m.culture].name + ","; - var population = m.population * urbanization.value * populationRate.value * 1000; + const population = m.population * urbanization.value * populationRate.value * 1000; data += population + "\n"; }); - var dataBlob = new Blob([data],{type:"text/plain"}); - var url = window.URL.createObjectURL(dataBlob); - var link = document.createElement("a"); + const dataBlob = new Blob([data], {type: "text/plain"}); + const url = window.URL.createObjectURL(dataBlob); + const link = document.createElement("a"); document.body.appendChild(link); link.download = "countries_data" + Date.now() + ".csv"; link.href = url; @@ -7356,8 +7439,8 @@ function fantasyMap() { Cancel: function() {$(this).dialog("close");}, Remove: function() { $(this).dialog("close"); - var state = +$("#burgsEditor").attr("data-state"); - var region = states[state].capital === "neutral" ? "neutral" : state; + const state = +$("#burgsEditor").attr("data-state"); + const region = states[state].capital === "neutral" ? "neutral" : state; $("#burgsBody").empty(); manors.map(function(m) { if (m.region !== region) {return;} @@ -7390,8 +7473,8 @@ function fantasyMap() { if (id === "regenerateBurgNames") { var s = +$("#burgsEditor").attr("data-state"); $(".burgName").each(function(e, i) { - var b = +(this.parentNode.id).slice(5); - var name = generateName(manors[b].culture); + const b = +(this.parentNode.id).slice(5); + const name = generateName(manors[b].culture); $(this).val(name); $(this).parent().attr("data-burg", name); manors[b].name = name; @@ -7412,18 +7495,18 @@ function fantasyMap() { if (id === "toggleScaleBar") {$("#scaleBar").toggleClass("hidden");} if (id === "addRuler") { $("#ruler").show(); - var rulerNew = ruler.append("g").attr("class", "linear").call(d3.drag().on("start", elementDrag)); - var factor = rn(1 / Math.pow(scale, 0.3), 1); - var y = Math.floor(Math.random() * graphHeight * 0.5 + graphHeight * 0.25); - var x1 = graphWidth * 0.2, x2 = graphWidth * 0.8; - var dash = rn(30 / distanceScale.value, 2); + const rulerNew = ruler.append("g").attr("class", "linear").call(d3.drag().on("start", elementDrag)); + const factor = rn(1 / Math.pow(scale, 0.3), 1); + const y = Math.floor(Math.random() * graphHeight * 0.5 + graphHeight * 0.25); + const x1 = graphWidth * 0.2, x2 = graphWidth * 0.8; + const dash = rn(30 / distanceScale.value, 2); rulerNew.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("class", "white").attr("stroke-width", factor); rulerNew.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("class", "gray").attr("stroke-width", factor).attr("stroke-dasharray", dash); rulerNew.append("circle").attr("r", 2 * factor).attr("stroke-width", 0.5 * factor).attr("cx", x1).attr("cy", y).attr("data-edge", "left").call(d3.drag().on("drag", rulerEdgeDrag)); rulerNew.append("circle").attr("r", 2 * factor).attr("stroke-width", 0.5 * factor).attr("cx", x2).attr("cy", y).attr("data-edge", "rigth").call(d3.drag().on("drag", rulerEdgeDrag)); rulerNew.append("circle").attr("r", 1.2 * factor).attr("stroke-width", 0.3 * factor).attr("cx", graphWidth / 2).attr("cy", y).attr("class", "center").call(d3.drag().on("start", rulerCenterDrag)); - var dist = rn(x2 - x1); - var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; + const dist = rn(x2 - x1); + const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; rulerNew.append("text").attr("x", graphWidth / 2).attr("y", y).attr("dy", -1).attr("data-dist", dist).text(label).text(label).on("click", removeParent).attr("font-size", 10 * factor); return; } @@ -7497,9 +7580,9 @@ function fantasyMap() { if (customization === 1) { if (id === "paintBrushes") {openBrushesPanel();} if (id === "rescaleExecute") { - var subject = rescaleLower.value + "-" + rescaleHigher.value; - var sign = conditionSign.value; - var modifier = rescaleModifier.value; + const subject = rescaleLower.value + "-" + rescaleHigher.value; + const sign = conditionSign.value; + let modifier = rescaleModifier.value; if (sign === "×") {modifyHeights(subject, 0, +modifier);} if (sign === "÷") {modifyHeights(subject, 0, (1 / modifier));} if (sign === "+") {modifyHeights(subject, +modifier, 1);} @@ -7601,8 +7684,8 @@ function fantasyMap() { var el = viewbox.select("#"+styleElementSelect.value); var mod = id === "styleFontPlus" ? 1.1 : 0.9; el.selectAll("g").each(function() { - var el = d3.select(this); - var size = rn(el.attr("data-size") * mod, 2); + const el = d3.select(this); + let size = rn(el.attr("data-size") * mod, 2); if (size < 2) {size = 2;} el.attr("data-size", size).attr("font-size", rn((size + (size / scale)) / 2, 2)); }); @@ -7658,11 +7741,11 @@ function fantasyMap() { // support save options $("#saveDropdown > div").click(function() { - var id = this.id; - var dns_allow_popup_message = localStorage.getItem("dns_allow_popup_message"); + const id = this.id; + let dns_allow_popup_message = localStorage.getItem("dns_allow_popup_message"); if (!dns_allow_popup_message) { localStorage.clear(); - var message = "Generator uses pop-up window to download files. "; + let message = "Generator uses pop-up window to download files. "; message += "Please ensure your browser does not block popups. "; message += "Please check browser settings and turn off adBlocker if it is enabled"; alertMessage.innerHTML = message; @@ -7827,15 +7910,15 @@ function fantasyMap() { // templateEditor Button handlers $("#templateTools > button").on("click", function() { - var id = this.id; + let id = this.id; id = id.replace("template", ""); if (id === "Mountain") { - var steps = $("#templateBody > div").length; + const steps = $("#templateBody > div").length; if (steps > 0) return; } $("#templateBody").attr("data-changed", 1); $("#templateBody").append('