mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
feat: style scale bar
This commit is contained in:
parent
fec5f421ad
commit
b9f3ff6da6
25 changed files with 540 additions and 246 deletions
18
index.css
18
index.css
|
|
@ -1876,12 +1876,6 @@ div.editorLine {
|
|||
margin: 0.4em 0 0 -0.9em;
|
||||
}
|
||||
|
||||
#barBackColor {
|
||||
width: 3.5em;
|
||||
padding: 0px;
|
||||
height: 1.2em;
|
||||
}
|
||||
|
||||
#ruler {
|
||||
cursor: move;
|
||||
fill: none;
|
||||
|
|
@ -1921,18 +1915,6 @@ div.editorLine {
|
|||
stroke: #737373;
|
||||
}
|
||||
|
||||
#scaleBar {
|
||||
stroke: none;
|
||||
fill: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#scaleBar text {
|
||||
fill: #353540;
|
||||
text-anchor: middle;
|
||||
font-family: var(--serif);
|
||||
}
|
||||
|
||||
#militaryOptionsTable select {
|
||||
border: 1px solid #d4d4d4;
|
||||
}
|
||||
|
|
|
|||
146
index.html
146
index.html
|
|
@ -366,7 +366,9 @@
|
|||
</mask>
|
||||
</defs>
|
||||
<g id="viewbox"></g>
|
||||
<g id="scaleBar"></g>
|
||||
<g id="scaleBar">
|
||||
<rect id="scaleBarBack"></rect>
|
||||
</g>
|
||||
<g id="vignette" mask="url(#vignette-mask)">
|
||||
<rect x="0" y="0" width="100%" height="100%" />
|
||||
</g>
|
||||
|
|
@ -799,6 +801,7 @@
|
|||
<option value="rivers">Rivers</option>
|
||||
<option value="routes">Routes</option>
|
||||
<option value="ruler">Rulers</option>
|
||||
<option value="scaleBar">Scale Bar</option>
|
||||
<option value="regions" selected>States</option>
|
||||
<option value="temperature">Temperature</option>
|
||||
<option value="texture">Texture</option>
|
||||
|
|
@ -1446,6 +1449,84 @@
|
|||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tbody id="styleScaleBar">
|
||||
<tr data-tip="Set bar and font size">
|
||||
<td>Size</td>
|
||||
<td>
|
||||
<span>Bar </span>
|
||||
<input id="styleScaleBarSize" type="number" min=".5" max="5" step=".1" />
|
||||
<span>Font </span>
|
||||
<input id="styleScaleBarFontSize" type="number" min="1" max="100" step=".1" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set position of the Scale bar bottom right corner (in percents)">
|
||||
<td>Position</td>
|
||||
<td>
|
||||
<span>x </span>
|
||||
<input id="styleScaleBarPositionX" type="number" min="0" max="100" step="0.1" style="width: 5em" />
|
||||
<span>y </span>
|
||||
<input id="styleScaleBarPositionY" type="number" min="0" max="100" step="0.1" style="width: 5em" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Type scale bar label, leave blank to hide label">
|
||||
<td>Label</td>
|
||||
<td>
|
||||
<input id="styleScaleBarLabel" type="text" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set background opacity. 0: transparent, 1: solid">
|
||||
<td>Back opacity</td>
|
||||
<td>
|
||||
<input id="styleScaleBarBackgroundOpacityInput" type="range" min="0" max="1" step="0.01" />
|
||||
<output id="styleScaleBarBackgroundOpacityOutput"></output>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set background fill color">
|
||||
<td>Back fill</td>
|
||||
<td>
|
||||
<input id="styleScaleBarBackgroundFillInput" type="color" />
|
||||
<output id="styleScaleBarBackgroundFillOutput"></output>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set background stroke color and width">
|
||||
<td>Back stroke</td>
|
||||
<td>
|
||||
<input id="styleScaleBarBackgroundStrokeInput" type="color" />
|
||||
<output id="styleScaleBarBackgroundStrokeOutput"></output>
|
||||
|
||||
<span>Width </span>
|
||||
<input
|
||||
id="styleScaleBarBackgroundStrokeWidth"
|
||||
type="number"
|
||||
min="0"
|
||||
max="10"
|
||||
step="0.1"
|
||||
style="width: 5em"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Set background element padding: top, right, bottom, left (in pixels)">
|
||||
<td>Back padding</td>
|
||||
<td style="display: flex; gap: 4px">
|
||||
<input id="styleScaleBarBackgroundPaddingTop" type="number" min="0" max="100" style="width: 5em" />
|
||||
<input id="styleScaleBarBackgroundPaddingRight" type="number" min="0" max="100" style="width: 5em" />
|
||||
<input id="styleScaleBarBackgroundPaddingBottom" type="number" min="0" max="100" style="width: 5em" />
|
||||
<input id="styleScaleBarBackgroundPaddingLeft" type="number" min="0" max="100" style="width: 5em" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Select background filter">
|
||||
<td>Back filter</td>
|
||||
<td><select id="styleScaleBarBackgroundFilter" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="mapFilters" data-tip="Set a filter to be applied to the map in general">
|
||||
|
|
@ -5132,49 +5213,6 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div class="unitsHeader">
|
||||
<span class="icon-minus"></span>
|
||||
<div>Scale bar:</div>
|
||||
</div>
|
||||
|
||||
<div data-tip="Set scale bar size">
|
||||
<div>Bar size:</div>
|
||||
<input id="barSizeOutput" data-stored="barSize" type="range" min=".5" max="5" value="2" step=".1" />
|
||||
<input id="barSizeInput" data-stored="barSize" type="number" min=".5" max="5" value="2" step=".1" />
|
||||
</div>
|
||||
|
||||
<div data-tip="Type scale bar label, leave blank to hide label">
|
||||
<div>Bar label:</div>
|
||||
<input id="barLabel" data-stored="barLabel" type="text" placeholder="hidden" value="" />
|
||||
</div>
|
||||
|
||||
<div data-tip="Set background for Scale bar">
|
||||
<div>Bar background:</div>
|
||||
<input
|
||||
id="barBackOpacity"
|
||||
data-stored="barBackOpacity"
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
value=".2"
|
||||
step=".01"
|
||||
/>
|
||||
<input id="barBackColor" data-stored="barBackColor" type="color" value="#ffffff" />
|
||||
</div>
|
||||
|
||||
<div data-tip="Set position of the Scale bar bottom right corner in percents">
|
||||
<div>Bar position:</div>
|
||||
x:<input id="barPosX" data-stored="barPosX" type="number" min="0" max="100" step=".1" value="99" /> y:<input
|
||||
id="barPosY"
|
||||
data-stored="barPosY"
|
||||
type="number"
|
||||
min="0"
|
||||
max="100"
|
||||
step=".1"
|
||||
value="99"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="unitsHeader">
|
||||
<span class="icon-male"></span>
|
||||
<div>Population:</div>
|
||||
|
|
@ -7994,16 +8032,16 @@
|
|||
<script src="libs/lineclip.min.js"></script>
|
||||
<script src="libs/alea.min.js"></script>
|
||||
<script src="modules/fonts.js?v=1.89.18"></script>
|
||||
<script src="modules/ui/layers.js?v=1.94.00"></script>
|
||||
<script src="modules/ui/measurers.js?v=1.94.03"></script>
|
||||
<script src="modules/ui/stylePresets.js?v=1.95.00"></script>
|
||||
<script src="modules/ui/layers.js?v=1.96.00"></script>
|
||||
<script src="modules/ui/measurers.js?v=1.96.00"></script>
|
||||
<script src="modules/ui/stylePresets.js?v=1.96.00"></script>
|
||||
|
||||
<script src="modules/ui/general.js?v=1.94.01"></script>
|
||||
<script src="modules/ui/options.js?v=1.94.06"></script>
|
||||
<script src="main.js?v=1.94.05"></script>
|
||||
<script src="modules/ui/options.js?v=1.96.00"></script>
|
||||
<script src="main.js?v=1.96.00"></script>
|
||||
|
||||
<script defer src="modules/relief-icons.js"></script>
|
||||
<script defer src="modules/ui/style.js?v=1.95.00"></script>
|
||||
<script defer src="modules/ui/style.js?v=1.96.00"></script>
|
||||
<script defer src="modules/ui/editors.js?v=1.93.10"></script>
|
||||
<script defer src="modules/ui/tools.js?v=1.92.00"></script>
|
||||
<script defer src="modules/ui/world-configurator.js?v=1.91.05"></script>
|
||||
|
|
@ -8022,7 +8060,7 @@
|
|||
<script defer src="modules/ui/rivers-creator.js?v=1.89.13"></script>
|
||||
<script defer src="modules/ui/relief-editor.js"></script>
|
||||
<script defer src="modules/ui/burg-editor.js"></script>
|
||||
<script defer src="modules/ui/units-editor.js?v=1.94.02"></script>
|
||||
<script defer src="modules/ui/units-editor.js?v=1.96.00"></script>
|
||||
<script defer src="modules/ui/notes-editor.js?v=1.93.09"></script>
|
||||
<script defer src="modules/ui/diplomacy-editor.js?v=1.88.04"></script>
|
||||
<script defer src="modules/ui/zones-editor.js"></script>
|
||||
|
|
@ -8041,10 +8079,10 @@
|
|||
<script defer src="modules/coa-renderer.js?v=1.94.00"></script>
|
||||
<script defer src="libs/rgbquant.min.js"></script>
|
||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||
<script defer src="modules/io/save.js?v=1.93.02"></script>
|
||||
<script defer src="modules/io/load.js?v=1.95.00"></script>
|
||||
<script defer src="modules/io/save.js?v=1.96.00"></script>
|
||||
<script defer src="modules/io/load.js?v=1.96.00"></script>
|
||||
<script defer src="modules/io/cloud.js?v=1.94.04"></script>
|
||||
<script defer src="modules/io/export.js?v=1.94.03"></script>
|
||||
<script defer src="modules/io/export.js?v=1.96.00"></script>
|
||||
<script defer src="modules/io/formats.js"></script>
|
||||
|
||||
<!-- Web Components -->
|
||||
|
|
|
|||
1
main.js
1
main.js
|
|
@ -135,7 +135,6 @@ fogging
|
|||
.attr("filter", "url(#splotch)");
|
||||
|
||||
// assign events separately as not a viewbox child
|
||||
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());
|
||||
|
|
|
|||
|
|
@ -736,4 +736,38 @@ export function resolveVersionConflicts(version) {
|
|||
.style("display", "none");
|
||||
vignette.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
||||
}
|
||||
|
||||
if (version < 1.96) {
|
||||
// v1.96.00 moved scaleBar options from units editor to style
|
||||
d3.select("#scaleBar").remove();
|
||||
|
||||
scaleBar = svg
|
||||
.insert("g", "#viewbox + *")
|
||||
.attr("id", "scaleBar")
|
||||
.attr("opacity", 1)
|
||||
.attr("fill", "#353540")
|
||||
.attr("font-size", 10)
|
||||
.attr("data-size", 2)
|
||||
.attr("data-x", 99)
|
||||
.attr("data-y", 99)
|
||||
.attr("data-label", "");
|
||||
|
||||
scaleBar
|
||||
.append("rect")
|
||||
.attr("id", "scaleBarBack")
|
||||
.attr("opacity", 0.2)
|
||||
.attr("fill", "#ffffff")
|
||||
.attr("stroke", "#000000")
|
||||
.attr("stroke-width", 1)
|
||||
.attr("filter", "url(#blur5)")
|
||||
.attr("data-top", 20)
|
||||
.attr("data-right", 15)
|
||||
.attr("data-bottom", 15)
|
||||
.attr("data-left", 10);
|
||||
|
||||
drawScaleBar(scaleBar, scale);
|
||||
fitScaleBar(scaleBar, svgWidth, svgHeight);
|
||||
|
||||
if (!layerIsOn("toggleScaleBar")) scaleBar.style("display", "none");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,12 +88,6 @@ function getSettings() {
|
|||
heightUnit: heightUnit.value,
|
||||
heightExponent: heightExponentInput.value,
|
||||
temperatureScale: temperatureScale.value,
|
||||
barSize: barSizeInput.value,
|
||||
barLabel: barLabel.value,
|
||||
barBackOpacity: barBackOpacity.value,
|
||||
barBackColor: barBackColor.value,
|
||||
barPosX: barPosX.value,
|
||||
barPosY: barPosY.value,
|
||||
populationRate: populationRate,
|
||||
urbanization: urbanization,
|
||||
mapSize: mapSizeOutput.value,
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ async function parseLoadedData(data) {
|
|||
|
||||
INFO && console.group("Loaded Map " + seed);
|
||||
|
||||
// TODO: move all to options object
|
||||
void (function parseSettings() {
|
||||
const settings = data[1].split("|");
|
||||
if (settings[0]) applyOption(distanceUnitInput, settings[0]);
|
||||
|
|
@ -226,23 +227,16 @@ async function parseLoadedData(data) {
|
|||
if (settings[3]) applyOption(heightUnit, settings[3]);
|
||||
if (settings[4]) heightExponentInput.value = heightExponentOutput.value = settings[4];
|
||||
if (settings[5]) temperatureScale.value = settings[5];
|
||||
if (settings[6]) barSizeInput.value = barSizeOutput.value = settings[6];
|
||||
if (settings[7] !== undefined) barLabel.value = settings[7];
|
||||
if (settings[8] !== undefined) barBackOpacity.value = settings[8];
|
||||
if (settings[9]) barBackColor.value = settings[9];
|
||||
if (settings[10]) barPosX.value = settings[10];
|
||||
if (settings[11]) barPosY.value = settings[11];
|
||||
// setting 6-11 (scaleBar) are part of style now, kept as "" in newer versions for compatibility
|
||||
if (settings[12]) populationRate = populationRateInput.value = populationRateOutput.value = settings[12];
|
||||
if (settings[13]) urbanization = urbanizationInput.value = urbanizationOutput.value = settings[13];
|
||||
if (settings[14]) mapSizeInput.value = mapSizeOutput.value = minmax(settings[14], 1, 100);
|
||||
if (settings[15]) latitudeInput.value = latitudeOutput.value = minmax(settings[15], 0, 100);
|
||||
if (settings[18]) precInput.value = precOutput.value = settings[18];
|
||||
|
||||
if (settings[19]) options = JSON.parse(settings[19]);
|
||||
// setting 16 and 17 (temperature) are part of options now, kept as "" in newer versions for compatibility
|
||||
if (settings[16]) options.temperatureEquator = +settings[16];
|
||||
if (settings[17]) options.temperatureNorthPole = options.temperatureSouthPole = +settings[17];
|
||||
|
||||
if (settings[20]) mapName.value = settings[20];
|
||||
if (settings[21]) hideLabels.checked = +settings[21];
|
||||
if (settings[22]) stylePreset.value = settings[22];
|
||||
|
|
@ -453,7 +447,6 @@ async function parseLoadedData(data) {
|
|||
})();
|
||||
|
||||
void (function restoreEvents() {
|
||||
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());
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ function prepareMapData() {
|
|||
heightUnit.value,
|
||||
heightExponentInput.value,
|
||||
temperatureScale.value,
|
||||
barSizeInput.value,
|
||||
barLabel.value,
|
||||
barBackOpacity.value,
|
||||
barBackColor.value,
|
||||
barPosX.value,
|
||||
barPosY.value,
|
||||
"", // previously used for barSize.value
|
||||
"", // previously used for barLabel.value
|
||||
"", // previously used for barBackColor.value
|
||||
"", // previously used for barBackColor.value
|
||||
"", // previously used for barPosX.value
|
||||
"", // previously used for barPosY.value
|
||||
populationRate,
|
||||
urbanization,
|
||||
mapSizeOutput.value,
|
||||
|
|
|
|||
|
|
@ -1670,10 +1670,7 @@ function toggleLabels(event) {
|
|||
invokeActiveZooming();
|
||||
if (event && isCtrlClick(event)) editStyle("labels");
|
||||
} else {
|
||||
if (event && isCtrlClick(event)) {
|
||||
editStyle("labels");
|
||||
return;
|
||||
}
|
||||
if (event && isCtrlClick(event)) return editStyle("labels");
|
||||
turnButtonOff("toggleLabels");
|
||||
labels.style("display", "none");
|
||||
}
|
||||
|
|
@ -1685,10 +1682,7 @@ function toggleIcons(event) {
|
|||
$("#icons").fadeIn();
|
||||
if (event && isCtrlClick(event)) editStyle("burgIcons");
|
||||
} else {
|
||||
if (event && isCtrlClick(event)) {
|
||||
editStyle("burgIcons");
|
||||
return;
|
||||
}
|
||||
if (event && isCtrlClick(event)) return editStyle("burgIcons");
|
||||
turnButtonOff("toggleIcons");
|
||||
$("#icons").fadeOut();
|
||||
}
|
||||
|
|
@ -1701,10 +1695,7 @@ function toggleRulers(event) {
|
|||
rulers.draw();
|
||||
ruler.style("display", null);
|
||||
} else {
|
||||
if (event && isCtrlClick(event)) {
|
||||
editStyle("ruler");
|
||||
return;
|
||||
}
|
||||
if (event && isCtrlClick(event)) return editStyle("ruler");
|
||||
turnButtonOff("toggleRulers");
|
||||
ruler.selectAll("*").remove();
|
||||
ruler.style("display", "none");
|
||||
|
|
@ -1715,17 +1706,113 @@ function toggleScaleBar(event) {
|
|||
if (!layerIsOn("toggleScaleBar")) {
|
||||
turnButtonOn("toggleScaleBar");
|
||||
$("#scaleBar").fadeIn();
|
||||
if (event && isCtrlClick(event)) editUnits();
|
||||
if (event && isCtrlClick(event)) editStyle("scaleBar");
|
||||
} else {
|
||||
if (event && isCtrlClick(event)) {
|
||||
editUnits();
|
||||
return;
|
||||
}
|
||||
if (event && isCtrlClick(event)) return editStyle("scaleBar");
|
||||
$("#scaleBar").fadeOut();
|
||||
turnButtonOff("toggleScaleBar");
|
||||
}
|
||||
}
|
||||
|
||||
function drawScaleBar(scaleBar, scaleLevel) {
|
||||
if (!scaleBar.size() || scaleBar.style("display") === "none") return;
|
||||
|
||||
const distanceScale = +distanceScaleInput.value;
|
||||
const unit = distanceUnitInput.value;
|
||||
const size = +scaleBar.attr("data-size");
|
||||
|
||||
const length = (function () {
|
||||
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); // round to 100
|
||||
else if (val > 9) val = rn(val, -1); // round to 10
|
||||
else val = rn(val); // round to 1
|
||||
const length = (val * scaleLevel) / distanceScale; // actual length in pixels on this scale
|
||||
return length;
|
||||
})();
|
||||
|
||||
scaleBar.select("#scaleBarContent").remove(); // redraw content every time
|
||||
const content = scaleBar.append("g").attr("id", "scaleBarContent");
|
||||
|
||||
const lines = content.append("g");
|
||||
lines
|
||||
.append("line")
|
||||
.attr("x1", 0.5)
|
||||
.attr("y1", 0)
|
||||
.attr("x2", length + size - 0.5)
|
||||
.attr("y2", 0)
|
||||
.attr("stroke-width", size)
|
||||
.attr("stroke", "white");
|
||||
lines
|
||||
.append("line")
|
||||
.attr("x1", 0)
|
||||
.attr("y1", size)
|
||||
.attr("x2", length + size)
|
||||
.attr("y2", size)
|
||||
.attr("stroke-width", size)
|
||||
.attr("stroke", "#3d3d3d");
|
||||
lines
|
||||
.append("line")
|
||||
.attr("x1", 0)
|
||||
.attr("y1", 0)
|
||||
.attr("x2", length + size)
|
||||
.attr("y2", 0)
|
||||
.attr("stroke-width", rn(size * 3, 2))
|
||||
.attr("stroke-dasharray", size + " " + rn(length / 5 - size, 2))
|
||||
.attr("stroke", "#3d3d3d");
|
||||
|
||||
const texts = content.append("g").attr("text-anchor", "middle").attr("font-family", "var(--serif)");
|
||||
texts
|
||||
.selectAll("text")
|
||||
.data(d3.range(0, 6))
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("x", d => rn((d * length) / 5, 2))
|
||||
.attr("y", 0)
|
||||
.attr("dy", "-.6em")
|
||||
.text(d => rn((((d * length) / 5) * distanceScale) / scaleLevel) + (d < 5 ? "" : " " + unit));
|
||||
|
||||
const label = scaleBar.attr("data-label");
|
||||
if (label) {
|
||||
texts
|
||||
.append("text")
|
||||
.attr("x", (length + 1) / 2)
|
||||
.attr("dy", ".6em")
|
||||
.attr("dominant-baseline", "text-before-edge")
|
||||
.text(label);
|
||||
}
|
||||
|
||||
const scaleBarBack = scaleBar.select("#scaleBarBack");
|
||||
if (scaleBarBack.size()) {
|
||||
const bbox = content.node().getBBox();
|
||||
const paddingTop = +scaleBarBack.attr("data-top") || 0;
|
||||
const paddingLeft = +scaleBarBack.attr("data-left") || 0;
|
||||
const paddingRight = +scaleBarBack.attr("data-right") || 0;
|
||||
const paddingBottom = +scaleBarBack.attr("data-bottom") || 0;
|
||||
|
||||
scaleBar
|
||||
.select("#scaleBarBack")
|
||||
.attr("x", -paddingLeft)
|
||||
.attr("y", -paddingTop)
|
||||
.attr("width", bbox.width + paddingRight)
|
||||
.attr("height", bbox.height + paddingBottom);
|
||||
}
|
||||
}
|
||||
|
||||
// fit ScaleBar to screen size
|
||||
function fitScaleBar(scaleBar, fullWidth, fullHeight) {
|
||||
if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return;
|
||||
|
||||
const posX = +scaleBar.attr("data-x") || 99;
|
||||
const posY = +scaleBar.attr("data-y") || 99;
|
||||
const bbox = scaleBar.select("rect").node().getBBox();
|
||||
|
||||
const x = rn((fullWidth * posX) / 100 - bbox.width + 10);
|
||||
const y = rn((fullHeight * posY) / 100 - bbox.height + 20);
|
||||
scaleBar.attr("transform", `translate(${x},${y})`);
|
||||
}
|
||||
|
||||
function toggleZones(event) {
|
||||
if (!layerIsOn("toggleZones")) {
|
||||
turnButtonOn("toggleZones");
|
||||
|
|
@ -1748,10 +1835,7 @@ function toggleEmblems(event) {
|
|||
$("#emblems").fadeIn();
|
||||
if (event && isCtrlClick(event)) editStyle("emblems");
|
||||
} else {
|
||||
if (event && isCtrlClick(event)) {
|
||||
editStyle("emblems");
|
||||
return;
|
||||
}
|
||||
if (event && isCtrlClick(event)) return editStyle("emblems");
|
||||
$("#emblems").fadeOut();
|
||||
turnButtonOff("toggleEmblems");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -532,101 +532,3 @@ class Planimeter extends Measurer {
|
|||
this.el.select("text").attr("x", c[0]).attr("y", c[1]).text(area);
|
||||
}
|
||||
}
|
||||
|
||||
// Scale bar
|
||||
function drawScaleBar(scaleBar, scaleLevel) {
|
||||
if (!scaleBar.size() || scaleBar.style("display") === "none") return;
|
||||
scaleBar.selectAll("*").remove(); // fully redraw every time
|
||||
|
||||
const distanceScale = +distanceScaleInput.value;
|
||||
const unit = distanceUnitInput.value;
|
||||
const size = +barSizeInput.value;
|
||||
|
||||
// calculate size
|
||||
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);
|
||||
// round to 100
|
||||
else if (val > 9) val = rn(val, -1);
|
||||
// round to 10
|
||||
else val = rn(val); // round to 1
|
||||
const length = (val * scaleLevel) / distanceScale; // actual length in pixels on this scale
|
||||
|
||||
scaleBar
|
||||
.append("line")
|
||||
.attr("x1", 0.5)
|
||||
.attr("y1", 0)
|
||||
.attr("x2", length + size - 0.5)
|
||||
.attr("y2", 0)
|
||||
.attr("stroke-width", size)
|
||||
.attr("stroke", "white");
|
||||
scaleBar
|
||||
.append("line")
|
||||
.attr("x1", 0)
|
||||
.attr("y1", size)
|
||||
.attr("x2", length + size)
|
||||
.attr("y2", size)
|
||||
.attr("stroke-width", size)
|
||||
.attr("stroke", "#3d3d3d");
|
||||
const dash = size + " " + rn(length / 5 - size, 2);
|
||||
scaleBar
|
||||
.append("line")
|
||||
.attr("x1", 0)
|
||||
.attr("y1", 0)
|
||||
.attr("x2", length + size)
|
||||
.attr("y2", 0)
|
||||
.attr("stroke-width", rn(size * 3, 2))
|
||||
.attr("stroke-dasharray", dash)
|
||||
.attr("stroke", "#3d3d3d");
|
||||
|
||||
const fontSize = rn(5 * size, 1);
|
||||
scaleBar
|
||||
.selectAll("text")
|
||||
.data(d3.range(0, 6))
|
||||
.enter()
|
||||
.append("text")
|
||||
.attr("x", d => rn((d * length) / 5, 2))
|
||||
.attr("y", 0)
|
||||
.attr("dy", "-.6em")
|
||||
.attr("font-size", fontSize)
|
||||
.text(d => rn((((d * length) / 5) * distanceScale) / scaleLevel) + (d < 5 ? "" : " " + unit));
|
||||
|
||||
if (barLabel.value !== "") {
|
||||
scaleBar
|
||||
.append("text")
|
||||
.attr("x", (length + 1) / 2)
|
||||
.attr("y", 2 * size)
|
||||
.attr("dominant-baseline", "text-before-edge")
|
||||
.attr("font-size", fontSize)
|
||||
.text(barLabel.value);
|
||||
}
|
||||
|
||||
const bbox = scaleBar.node().getBBox();
|
||||
// append backbround rectangle
|
||||
scaleBar
|
||||
.insert("rect", ":first-child")
|
||||
.attr("x", -10)
|
||||
.attr("y", -20)
|
||||
.attr("width", bbox.width + 10)
|
||||
.attr("height", bbox.height + 15)
|
||||
.attr("stroke-width", size)
|
||||
.attr("stroke", "none")
|
||||
.attr("filter", "url(#blur5)")
|
||||
.attr("fill", barBackColor.value)
|
||||
.attr("opacity", +barBackOpacity.value);
|
||||
}
|
||||
|
||||
// fit ScaleBar to screen size
|
||||
function fitScaleBar(scaleBar, fullWidth, fullHeight) {
|
||||
if (!scaleBar.select("rect").size() || scaleBar.style("display") === "none") return;
|
||||
|
||||
const px = isNaN(+barPosX.value) ? 0.99 : barPosX.value / 100;
|
||||
const py = isNaN(+barPosY.value) ? 0.99 : barPosY.value / 100;
|
||||
const bbox = scaleBar.select("rect").node().getBBox();
|
||||
|
||||
const x = rn(fullWidth * px - bbox.width + 10);
|
||||
const y = rn(fullHeight * py - bbox.height + 20);
|
||||
scaleBar.attr("transform", `translate(${x},${y})`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -774,7 +774,7 @@ function showExportPane() {
|
|||
}
|
||||
|
||||
async function exportToJson(type) {
|
||||
const {exportToJson} = await import("../dynamic/export-json.js?v=1.93.03");
|
||||
const {exportToJson} = await import("../dynamic/export-json.js?v=1.96.00");
|
||||
exportToJson(type);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
byId("styleFilterInput").innerHTML = allOptions;
|
||||
byId("styleStatesBodyFilter").innerHTML = allOptions;
|
||||
byId("styleScaleBarBackgroundFilter").innerHTML = allOptions;
|
||||
}
|
||||
|
||||
// store some style inputs as options
|
||||
|
|
@ -94,13 +95,13 @@ function selectStyleElement() {
|
|||
}
|
||||
|
||||
// filter
|
||||
if (!["landmass", "legend", "regions"].includes(styleElement)) {
|
||||
if (!["landmass", "legend", "regions", "scaleBar"].includes(styleElement)) {
|
||||
styleFilter.style.display = "block";
|
||||
styleFilterInput.value = el.attr("filter") || "";
|
||||
}
|
||||
|
||||
// fill
|
||||
if (["rivers", "lakes", "landmass", "prec", "ice", "fogging", "vignette"].includes(styleElement)) {
|
||||
if (["rivers", "lakes", "landmass", "prec", "ice", "fogging", "scaleBar", "vignette"].includes(styleElement)) {
|
||||
styleFill.style.display = "block";
|
||||
styleFillInput.value = styleFillOutput.value = el.attr("fill");
|
||||
}
|
||||
|
|
@ -356,6 +357,31 @@ function selectStyleElement() {
|
|||
if (auto) styleFilter.style.display = "none";
|
||||
}
|
||||
|
||||
if (styleElement === "scaleBar") {
|
||||
styleScaleBar.style.display = "block";
|
||||
|
||||
styleScaleBarSize.value = el.attr("data-size");
|
||||
styleScaleBarFontSize.value = el.attr("font-size");
|
||||
styleScaleBarPositionX.value = el.attr("data-x") || "99";
|
||||
styleScaleBarPositionY.value = el.attr("data-y") || "99";
|
||||
styleScaleBarLabel.value = el.attr("data-label") || "";
|
||||
|
||||
const scaleBarBack = el.select("#scaleBarBack");
|
||||
if (scaleBarBack.size()) {
|
||||
styleScaleBarBackgroundOpacityInput.value = styleScaleBarBackgroundOpacityOutput.value =
|
||||
scaleBarBack.attr("opacity");
|
||||
styleScaleBarBackgroundFillInput.value = styleScaleBarBackgroundFillOutput.value = scaleBarBack.attr("fill");
|
||||
styleScaleBarBackgroundStrokeInput.value = styleScaleBarBackgroundStrokeOutput.value =
|
||||
scaleBarBack.attr("stroke");
|
||||
styleScaleBarBackgroundStrokeWidth.value = scaleBarBack.attr("stroke-width");
|
||||
styleScaleBarBackgroundFilter.value = scaleBarBack.attr("filter");
|
||||
styleScaleBarBackgroundPaddingTop.value = scaleBarBack.attr("data-top");
|
||||
styleScaleBarBackgroundPaddingRight.value = scaleBarBack.attr("data-right");
|
||||
styleScaleBarBackgroundPaddingBottom.value = scaleBarBack.attr("data-bottom");
|
||||
styleScaleBarBackgroundPaddingLeft.value = scaleBarBack.attr("data-left");
|
||||
}
|
||||
}
|
||||
|
||||
if (styleElement === "vignette") {
|
||||
styleVignette.style.display = "block";
|
||||
|
||||
|
|
@ -1043,6 +1069,44 @@ styleVignetteBlur.addEventListener("input", function () {
|
|||
byId("vignette-rect")?.setAttribute("filter", `blur(${this.value}px)`);
|
||||
});
|
||||
|
||||
styleScaleBar.addEventListener("input", function (event) {
|
||||
const scaleBarBack = scaleBar.select("#scaleBarBack");
|
||||
if (!scaleBarBack.size()) return;
|
||||
|
||||
const {id, value} = event.target;
|
||||
|
||||
if (id === "styleScaleBarSize") scaleBar.attr("data-size", value);
|
||||
else if (id === "styleScaleBarFontSize") scaleBar.attr("font-size", value);
|
||||
else if (id === "styleScaleBarPositionX") scaleBar.attr("data-x", value);
|
||||
else if (id === "styleScaleBarPositionY") scaleBar.attr("data-y", value);
|
||||
else if (id === "styleScaleBarLabel") scaleBar.attr("data-label", value);
|
||||
else if (id === "styleScaleBarBackgroundOpacityInput") scaleBarBack.attr("opacity", value);
|
||||
else if (id === "styleScaleBarBackgroundFillInput") scaleBarBack.attr("fill", value);
|
||||
else if (id === "styleScaleBarBackgroundStrokeInput") scaleBarBack.attr("stroke", value);
|
||||
else if (id === "styleScaleBarBackgroundStrokeWidth") scaleBarBack.attr("stroke-width", value);
|
||||
else if (id === "styleScaleBarBackgroundFilter") scaleBarBack.attr("filter", value);
|
||||
else if (id === "styleScaleBarBackgroundPaddingTop") scaleBarBack.attr("data-top", value);
|
||||
else if (id === "styleScaleBarBackgroundPaddingRight") scaleBarBack.attr("data-right", value);
|
||||
else if (id === "styleScaleBarBackgroundPaddingBottom") scaleBarBack.attr("data-bottom", value);
|
||||
else if (id === "styleScaleBarBackgroundPaddingLeft") scaleBarBack.attr("data-left", value);
|
||||
|
||||
if (
|
||||
[
|
||||
"styleScaleBarSize",
|
||||
"styleScaleBarPositionX",
|
||||
"styleScaleBarPositionY",
|
||||
"styleScaleBarLabel",
|
||||
"styleScaleBarBackgroundPaddingLeft",
|
||||
"styleScaleBarBackgroundPaddingTop",
|
||||
"styleScaleBarBackgroundPaddingRight",
|
||||
"styleScaleBarBackgroundPaddingBottom"
|
||||
].includes(id)
|
||||
) {
|
||||
drawScaleBar(scaleBar, scale);
|
||||
fitScaleBar(scaleBar, svgWidth, svgHeight);
|
||||
}
|
||||
});
|
||||
|
||||
function updateElements() {
|
||||
// burgIcons to desired size
|
||||
burgIcons.selectAll("g").each(function () {
|
||||
|
|
|
|||
|
|
@ -301,7 +301,19 @@ function addStylePreset() {
|
|||
],
|
||||
"#fogging": ["opacity", "fill", "filter"],
|
||||
"#vignette": ["opacity", "fill", "filter"],
|
||||
"#vignette-rect": ["x", "y", "width", "height", "rx", "ry", "filter"]
|
||||
"#vignette-rect": ["x", "y", "width", "height", "rx", "ry", "filter"],
|
||||
"#scaleBar": ["opacity", "fill", "font-size", "data-size", "data-x", "data-y", "data-label"],
|
||||
"#scaleBarBack": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"filter",
|
||||
"data-top",
|
||||
"data-right",
|
||||
"data-bottom",
|
||||
"data-left"
|
||||
]
|
||||
};
|
||||
|
||||
for (const selector in attributes) {
|
||||
|
|
|
|||
|
|
@ -24,13 +24,6 @@ function editUnits() {
|
|||
byId("heightExponentInput").addEventListener("input", changeHeightExponent);
|
||||
byId("heightExponentOutput").addEventListener("input", changeHeightExponent);
|
||||
byId("temperatureScale").addEventListener("change", changeTemperatureScale);
|
||||
byId("barSizeOutput").addEventListener("input", renderScaleBar);
|
||||
byId("barSizeInput").addEventListener("input", renderScaleBar);
|
||||
byId("barLabel").addEventListener("input", renderScaleBar);
|
||||
byId("barPosX").addEventListener("input", fitScaleBar);
|
||||
byId("barPosY").addEventListener("input", fitScaleBar);
|
||||
byId("barBackOpacity").addEventListener("input", changeScaleBarOpacity);
|
||||
byId("barBackColor").addEventListener("input", changeScaleBarColor);
|
||||
|
||||
byId("populationRateOutput").addEventListener("input", changePopulationRate);
|
||||
byId("populationRateInput").addEventListener("change", changePopulationRate);
|
||||
|
|
@ -84,14 +77,6 @@ function editUnits() {
|
|||
if (layerIsOn("toggleTemp")) drawTemp();
|
||||
}
|
||||
|
||||
function changeScaleBarOpacity() {
|
||||
scaleBar.select("rect").attr("opacity", this.value);
|
||||
}
|
||||
|
||||
function changeScaleBarColor() {
|
||||
scaleBar.select("rect").attr("fill", this.value);
|
||||
}
|
||||
|
||||
function changePopulationRate() {
|
||||
populationRate = +this.value;
|
||||
}
|
||||
|
|
@ -129,19 +114,6 @@ function editUnits() {
|
|||
localStorage.removeItem("heightExponent");
|
||||
calculateTemperatures();
|
||||
|
||||
// scale bar
|
||||
barSizeOutput.value = barSizeInput.value = 2;
|
||||
barLabel.value = "";
|
||||
barBackOpacity.value = 0.2;
|
||||
barBackColor.value = "#ffffff";
|
||||
barPosX.value = barPosY.value = 99;
|
||||
|
||||
localStorage.removeItem("barSize");
|
||||
localStorage.removeItem("barLabel");
|
||||
localStorage.removeItem("barBackOpacity");
|
||||
localStorage.removeItem("barBackColor");
|
||||
localStorage.removeItem("barPosX");
|
||||
localStorage.removeItem("barPosY");
|
||||
renderScaleBar();
|
||||
|
||||
// population
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "0%",
|
||||
"ry": "0%",
|
||||
"filter": "blur(50px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(30px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,5 +400,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,5 +400,25 @@
|
|||
"rx": "10%",
|
||||
"ry": "10%",
|
||||
"filter": "blur(30px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,5 +394,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(30px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,5 +398,25 @@
|
|||
"rx": "5%",
|
||||
"ry": "5%",
|
||||
"filter": "blur(20px)"
|
||||
},
|
||||
"#scaleBar": {
|
||||
"opacity": 1,
|
||||
"fill": "#353540",
|
||||
"font-size": 10,
|
||||
"data-size": 2,
|
||||
"data-x": 99,
|
||||
"data-y": 99,
|
||||
"data-label": ""
|
||||
},
|
||||
"#scaleBarBack": {
|
||||
"opacity": 0.2,
|
||||
"fill": "#ffffff",
|
||||
"stroke": "#000000",
|
||||
"stroke-width": 1,
|
||||
"filter": "url(#blur5)",
|
||||
"data-top": 20,
|
||||
"data-right": 15,
|
||||
"data-bottom": 15,
|
||||
"data-left": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
// version and caching control
|
||||
const version = "1.95.00"; // generator version, update each time
|
||||
const version = "1.96.00"; // generator version, update each time
|
||||
|
||||
{
|
||||
document.title += " v" + version;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue