From a1f70afd57d64a81225b568b9d1b9868876c4821 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 19 Nov 2023 17:03:48 +0400 Subject: [PATCH] Fit map to screen size (#1018) * feat: fit map to screen size * chore: pump version --------- Co-authored-by: Azgaar --- index.html | 22 ++++----- main.js | 4 +- modules/io/load.js | 2 +- modules/submap.js | 2 +- modules/ui/general.js | 7 ++- modules/ui/measurers.js | 6 ++- modules/ui/options.js | 104 ++++++++++++++++++---------------------- 7 files changed, 67 insertions(+), 80 deletions(-) diff --git a/index.html b/index.html index 2d9cce78..f08fde8b 100644 --- a/index.html +++ b/index.html @@ -1410,9 +1410,11 @@

- + - + @@ -7934,7 +7930,7 @@ - + @@ -7943,9 +7939,9 @@ - - - + + + diff --git a/main.js b/main.js index 6d52dd97..a7f34a09 100644 --- a/main.js +++ b/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); diff --git a/modules/io/load.js b/modules/io/load.js index 9e4e5e5d..f2154872 100644 --- a/modules/io/load.js +++ b/modules/io/load.js @@ -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); diff --git a/modules/submap.js b/modules/submap.js index 0918d715..0c8be6c3 100644 --- a/modules/submap.js +++ b/modules/submap.js @@ -39,7 +39,7 @@ window.Submap = (function () { DEBUG && console.log("Using Options:", options); // create new grid - applyMapSize(); + applyGraphSize(); grid = generateGrid(); drawScaleBar(scale); diff --git a/modules/ui/general.js b/modules/ui/general.js index 083e2c8b..17f8886d 100644 --- a/modules/ui/general.js +++ b/modules/ui/general.js @@ -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]; diff --git a/modules/ui/measurers.js b/modules/ui/measurers.js index 54a6d9f8..0895cd47 100644 --- a/modules/ui/measurers.js +++ b/modules/ui/measurers.js @@ -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})`); } diff --git a/modules/ui/options.js b/modules/ui/options.js index 5ae560e6..e39253c6 100644 --- a/modules/ui/options.js +++ b/modules/ui/options.js @@ -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;
+ + Canvas size @@ -1420,13 +1422,7 @@ px - -