mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
Fit map to screen size (#1018)
* feat: fit map to screen size * chore: pump version --------- Co-authored-by: Azgaar <azgaar.fmg@yandex.com>
This commit is contained in:
parent
a349d40868
commit
a1f70afd57
7 changed files with 67 additions and 80 deletions
22
index.html
22
index.html
|
|
@ -1410,9 +1410,11 @@
|
|||
</p>
|
||||
<table>
|
||||
<tr
|
||||
data-tip="Canvas width and height in pixels. Defines map size on generation that cannot be changed later. Always keep canvas size equal to your screen size or less. The best option is to use the default value. For full-globe maps use aspect ratio 2:1"
|
||||
data-tip="Set original map size on generation. It cannot be changed later. Always keep canvas size equal to your screen size or less. The best option is to use the default value. For full-globe maps use aspect ratio 2:1"
|
||||
>
|
||||
<td></td>
|
||||
<td>
|
||||
<i data-tip="Restore default canvas size" id="restoreDefaultCanvasSize" class="icon-ccw"></i>
|
||||
</td>
|
||||
<td>Canvas size</td>
|
||||
<td>
|
||||
<input id="mapWidthInput" class="paired" type="number" min="240" value="960" />
|
||||
|
|
@ -1420,13 +1422,7 @@
|
|||
<input id="mapHeightInput" class="paired" type="number" min="135" value="540" />
|
||||
<span>px</span>
|
||||
</td>
|
||||
<td>
|
||||
<i
|
||||
data-tip="Toggle between the current screen size and the initial canvas size"
|
||||
id="toggleFullscreen"
|
||||
class="icon-resize-full-alt"
|
||||
></i>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr data-tip="Map seed number. Seed produces the same map only if canvas size and options are the same">
|
||||
|
|
@ -7934,7 +7930,7 @@
|
|||
<script src="modules/military-generator.js"></script>
|
||||
<script src="modules/markers-generator.js?v=1.93.04"></script>
|
||||
<script src="modules/coa-generator.js?v=1.91.05"></script>
|
||||
<script src="modules/submap.js?v=1.91.05"></script>
|
||||
<script src="modules/submap.js?v=1.94.01"></script>
|
||||
<script src="libs/polylabel.min.js"></script>
|
||||
<script src="libs/lineclip.min.js"></script>
|
||||
<script src="libs/alea.min.js"></script>
|
||||
|
|
@ -7943,9 +7939,9 @@
|
|||
<script src="modules/ui/measurers.js?v=1.87.02"></script>
|
||||
<script src="modules/ui/stylePresets.js?v=1.94.00"></script>
|
||||
|
||||
<script src="modules/ui/general.js?v=1.94.00"></script>
|
||||
<script src="modules/ui/options.js?v=1.94.00"></script>
|
||||
<script src="main.js?v=1.94.00"></script>
|
||||
<script src="modules/ui/general.js?v=1.94.01"></script>
|
||||
<script src="modules/ui/options.js?v=1.94.01"></script>
|
||||
<script src="main.js?v=1.94.01"></script>
|
||||
|
||||
<script defer src="modules/relief-icons.js"></script>
|
||||
<script defer src="modules/ui/style.js?v=1.94.00"></script>
|
||||
|
|
|
|||
4
main.js
4
main.js
|
|
@ -308,6 +308,7 @@ async function generateMapOnLoad() {
|
|||
await generate(); // generate map
|
||||
focusOn(); // based on searchParams focus on point, cell or burg from MFCG
|
||||
applyPreset(); // apply saved layers preset
|
||||
fitMapToScreen();
|
||||
}
|
||||
|
||||
// focus on coordinates, cell or burg provided in searchParams
|
||||
|
|
@ -607,7 +608,7 @@ async function generate(options) {
|
|||
setSeed(precreatedSeed);
|
||||
INFO && console.group("Generated Map " + seed);
|
||||
|
||||
applyMapSize();
|
||||
applyGraphSize();
|
||||
randomizeOptions();
|
||||
|
||||
if (shouldRegenerateGrid(grid, precreatedSeed)) grid = precreatedGraph || generateGrid();
|
||||
|
|
@ -1942,6 +1943,7 @@ const regenerateMap = debounce(async function (options) {
|
|||
if (ThreeD.options.isOn) ThreeD.redraw();
|
||||
if ($("#worldConfigurator").is(":visible")) editWorld();
|
||||
|
||||
fitMapToScreen();
|
||||
shouldShowLoading && hideLoading();
|
||||
clearMainTip();
|
||||
}, 250);
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ async function parseLoadedData(data) {
|
|||
}
|
||||
})();
|
||||
|
||||
changeMapSize();
|
||||
fitMapToScreen();
|
||||
|
||||
// remove href from emblems, to trigger rendering on load
|
||||
emblems.selectAll("use").attr("href", null);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ window.Submap = (function () {
|
|||
DEBUG && console.log("Using Options:", options);
|
||||
|
||||
// create new grid
|
||||
applyMapSize();
|
||||
applyGraphSize();
|
||||
grid = generateGrid();
|
||||
|
||||
drawScaleBar(scale);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
"use strict";
|
||||
// Module to store general UI functions
|
||||
// Module to store generic UI functions
|
||||
|
||||
// fit full-screen map if window is resized
|
||||
window.addEventListener("resize", function (e) {
|
||||
if (stored("mapWidth") && stored("mapHeight")) return;
|
||||
mapWidthInput.value = window.innerWidth;
|
||||
mapHeightInput.value = window.innerHeight;
|
||||
changeMapSize();
|
||||
fitMapToScreen();
|
||||
});
|
||||
|
||||
if (location.hostname !== "localhost" && location.hostname !== "127.0.0.1") {
|
||||
|
|
@ -28,7 +27,7 @@ const tipBackgroundMap = {
|
|||
error: "linear-gradient(0.1turn, #ffffff00, #e11d1dcc, #ffffff00)"
|
||||
};
|
||||
|
||||
function tip(tip = "Tip is undefined", main = false, type = "info", time = 0) {
|
||||
function tip(tip, main = false, type = "info", time = 0) {
|
||||
tooltip.innerHTML = tip;
|
||||
tooltip.style.background = tipBackgroundMap[type];
|
||||
|
||||
|
|
|
|||
|
|
@ -623,10 +623,12 @@ function drawScaleBar(scaleLevel) {
|
|||
// fit ScaleBar to canvas size
|
||||
function fitScaleBar() {
|
||||
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(svgWidth * px - bbox.width + 10),
|
||||
y = rn(svgHeight * py - bbox.height + 20);
|
||||
|
||||
const x = rn(svgWidth * px - bbox.width + 10);
|
||||
const y = rn(svgHeight * py - bbox.height + 20);
|
||||
scaleBar.attr("transform", `translate(${x},${y})`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ optionsContent.addEventListener("change", function (event) {
|
|||
|
||||
if (id === "zoomExtentMin" || id === "zoomExtentMax") changeZoomExtent(value);
|
||||
else if (id === "optionsSeed") generateMapWithSeed("seed change");
|
||||
else if (id === "uiSizeInput" || id === "uiSizeOutput") changeUIsize(value);
|
||||
else if (id === "uiSizeInput" || id === "uiSizeOutput") changeUiSize(value);
|
||||
else if (id === "shapeRendering") setRendering(value);
|
||||
else if (id === "yearInput") changeYear();
|
||||
else if (id === "eraInput") changeEra();
|
||||
|
|
@ -148,7 +148,7 @@ optionsContent.addEventListener("change", function (event) {
|
|||
|
||||
optionsContent.addEventListener("click", function (event) {
|
||||
const id = event.target.id;
|
||||
if (id === "toggleFullscreen") toggleFullscreen();
|
||||
if (id === "restoreDefaultCanvasSize") restoreDefaultCanvasSize();
|
||||
else if (id === "optionsMapHistory") showSeedHistoryDialog();
|
||||
else if (id === "optionsCopySeed") copyMapURL();
|
||||
else if (id === "optionsEraRegenerate") regenerateEra();
|
||||
|
|
@ -165,7 +165,7 @@ function mapSizeInputChange() {
|
|||
const $mapWidthInput = byId("mapWidthInput");
|
||||
const $mapHeightInput = byId("mapHeightInput");
|
||||
|
||||
changeMapSize();
|
||||
fitMapToScreen();
|
||||
localStorage.setItem("mapWidth", $mapWidthInput.value);
|
||||
localStorage.setItem("mapHeight", $mapHeightInput.value);
|
||||
|
||||
|
|
@ -173,79 +173,67 @@ function mapSizeInputChange() {
|
|||
const tooHigh = +$mapHeightInput.value > window.innerHeight;
|
||||
|
||||
if (tooWide || tooHigh) {
|
||||
const message = `Canvas size is larger than actual window size (${window.innerWidth} x ${window.innerHeight}). It can affect the performance if you are going to create a new map`;
|
||||
const message = `Canvas size is larger than window size (${window.innerWidth} x ${window.innerHeight}). It can affect performance`;
|
||||
tip(message, false, "warn", 4000);
|
||||
}
|
||||
}
|
||||
|
||||
// change svg size on manual size change or window resize (do not change graph size!)
|
||||
function changeMapSize() {
|
||||
// on map creation
|
||||
function applyGraphSize() {
|
||||
console.log("applyGraphSize");
|
||||
graphWidth = +mapWidthInput.value;
|
||||
graphHeight = +mapHeightInput.value;
|
||||
|
||||
landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
oceanLayers.select("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
fogging.selectAll("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight);
|
||||
defs.select("mask#fog > rect").attr("width", graphWidth).attr("height", graphHeight);
|
||||
defs.select("mask#water > rect").attr("width", graphWidth).attr("height", graphHeight);
|
||||
}
|
||||
|
||||
// on generate, on load, on resize, on canvas size change
|
||||
function fitMapToScreen() {
|
||||
console.log("fitMapToScreen");
|
||||
svgWidth = Math.min(+mapWidthInput.value, window.innerWidth);
|
||||
svgHeight = Math.min(+mapHeightInput.value, window.innerHeight);
|
||||
svg.attr("width", svgWidth).attr("height", svgHeight);
|
||||
|
||||
const maxWidth = Math.max(+mapWidthInput.value, graphWidth);
|
||||
const maxHeight = Math.max(+mapHeightInput.value, graphHeight);
|
||||
|
||||
zoom.translateExtent([
|
||||
const zoomExtent = [
|
||||
[0, 0],
|
||||
[maxWidth, maxHeight]
|
||||
]);
|
||||
[graphWidth, graphHeight]
|
||||
];
|
||||
|
||||
landmass.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
oceanPattern.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
oceanLayers.select("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
fogging.selectAll("rect").attr("x", 0).attr("y", 0).attr("width", maxWidth).attr("height", maxHeight);
|
||||
defs.select("mask#fog > rect").attr("width", maxWidth).attr("height", maxHeight);
|
||||
defs.select("mask#water > rect").attr("width", maxWidth).attr("height", maxHeight);
|
||||
const zoomMin = rn(Math.max(svgWidth / graphWidth, svgHeight / graphHeight), 2);
|
||||
zoomExtentMin.value = zoomMin;
|
||||
const zoomMax = +zoomExtentMax.value;
|
||||
|
||||
zoom.translateExtent(zoomExtent).scaleExtent([zoomMin, zoomMax]).scaleTo(svg, zoomMin);
|
||||
|
||||
fitScaleBar();
|
||||
if (window.fitLegendBox) fitLegendBox();
|
||||
}
|
||||
|
||||
// just apply canvas size that was already set
|
||||
function applyMapSize() {
|
||||
const zoomMin = +zoomExtentMin.value;
|
||||
const zoomMax = +zoomExtentMax.value;
|
||||
graphWidth = +mapWidthInput.value;
|
||||
graphHeight = +mapHeightInput.value;
|
||||
svgWidth = Math.min(graphWidth, window.innerWidth);
|
||||
svgHeight = Math.min(graphHeight, window.innerHeight);
|
||||
svg.attr("width", svgWidth).attr("height", svgHeight);
|
||||
zoom
|
||||
.translateExtent([
|
||||
[0, 0],
|
||||
[graphWidth, graphHeight]
|
||||
])
|
||||
.scaleExtent([zoomMin, zoomMax])
|
||||
.scaleTo(svg, zoomMin);
|
||||
}
|
||||
|
||||
function toggleFullscreen() {
|
||||
if (mapWidthInput.value != window.innerWidth || mapHeightInput.value != window.innerHeight) {
|
||||
mapWidthInput.value = window.innerWidth;
|
||||
mapHeightInput.value = window.innerHeight;
|
||||
localStorage.removeItem("mapHeight");
|
||||
localStorage.removeItem("mapWidth");
|
||||
} else {
|
||||
mapWidthInput.value = graphWidth;
|
||||
mapHeightInput.value = graphHeight;
|
||||
}
|
||||
changeMapSize();
|
||||
function restoreDefaultCanvasSize() {
|
||||
mapWidthInput.value = window.innerWidth;
|
||||
mapHeightInput.value = window.innerHeight;
|
||||
localStorage.removeItem("mapHeight");
|
||||
localStorage.removeItem("mapWidth");
|
||||
}
|
||||
|
||||
function toggleTranslateExtent(el) {
|
||||
const on = (el.dataset.on = +!+el.dataset.on);
|
||||
if (on)
|
||||
if (on) {
|
||||
zoom.translateExtent([
|
||||
[-graphWidth / 2, -graphHeight / 2],
|
||||
[graphWidth * 1.5, graphHeight * 1.5]
|
||||
]);
|
||||
else
|
||||
} else {
|
||||
zoom.translateExtent([
|
||||
[0, 0],
|
||||
[graphWidth, graphHeight]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// add voice options
|
||||
|
|
@ -309,12 +297,6 @@ function restoreSeed(id) {
|
|||
regeneratePrompt({seed});
|
||||
}
|
||||
|
||||
function restoreDefaultZoomExtent() {
|
||||
zoomExtentMin.value = 1;
|
||||
zoomExtentMax.value = 20;
|
||||
zoom.scaleExtent([1, 20]).scaleTo(svg, 1);
|
||||
}
|
||||
|
||||
function copyMapURL() {
|
||||
const locked = document.querySelectorAll("i.icon-lock").length; // check if some options are locked
|
||||
const search = `?seed=${optionsSeed.value}&width=${graphWidth}&height=${graphHeight}${
|
||||
|
|
@ -414,7 +396,7 @@ function changeStatesNumber(value) {
|
|||
labels.select("#countries").attr("data-size", Math.max(rn(18 - value / 6), 4));
|
||||
}
|
||||
|
||||
function changeUIsize(value) {
|
||||
function changeUiSize(value) {
|
||||
if (isNaN(+value) || +value < 0.5) return;
|
||||
|
||||
const max = getUImaxSize();
|
||||
|
|
@ -529,6 +511,12 @@ function changeZoomExtent(value) {
|
|||
zoom.scaleTo(svg, scale);
|
||||
}
|
||||
|
||||
function restoreDefaultZoomExtent() {
|
||||
zoomExtentMin.value = 1;
|
||||
zoomExtentMax.value = 20;
|
||||
zoom.scaleExtent([1, 20]).scaleTo(svg, 1);
|
||||
}
|
||||
|
||||
// restore options stored in localStorage
|
||||
function applyStoredOptions() {
|
||||
if (!stored("mapWidth") || !stored("mapHeight")) {
|
||||
|
|
@ -571,8 +559,8 @@ function applyStoredOptions() {
|
|||
if (stored("regions")) changeStatesNumber(stored("regions"));
|
||||
|
||||
uiSizeInput.max = uiSizeOutput.max = getUImaxSize();
|
||||
if (stored("uiSize")) changeUIsize(stored("uiSize"));
|
||||
else changeUIsize(minmax(rn(mapWidthInput.value / 1280, 1), 1, 2.5));
|
||||
if (stored("uiSize")) changeUiSize(stored("uiSize"));
|
||||
else changeUiSize(minmax(rn(mapWidthInput.value / 1280, 1), 1, 2.5));
|
||||
|
||||
// search params overwrite stored and default options
|
||||
const params = new URL(window.location.href).searchParams;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue