mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
zoom changes
This commit is contained in:
parent
c4663e7b9b
commit
8337a9b5ff
2 changed files with 124 additions and 0 deletions
122
main.js
122
main.js
|
|
@ -173,6 +173,8 @@ const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with defaul
|
|||
let scale = 1;
|
||||
let viewX = 0;
|
||||
let viewY = 0;
|
||||
// Track last applied zoom visibility bucket to avoid redundant DOM work
|
||||
let zoomVisibilityBucket = -1;
|
||||
|
||||
const onZoom = debounce(function () {
|
||||
const {k, x, y} = d3.event.transform;
|
||||
|
|
@ -567,6 +569,126 @@ function invokeActiveZooming() {
|
|||
const size = rn((10 / scale ** 0.3) * 2, 2);
|
||||
ruler.selectAll("text").attr("font-size", size);
|
||||
}
|
||||
|
||||
// Update zoom-based visibility for burgs and routes
|
||||
updateBurgsAndRoutesVisibility();
|
||||
}
|
||||
|
||||
// Toggle visibility of towns, labels and route types based on current zoom level
|
||||
function updateBurgsAndRoutesVisibility() {
|
||||
// Determine a coarse bucket from the continuous zoom scale to minimize toggles
|
||||
// Bucket 4: scale >= 7 (show everything)
|
||||
// Bucket 3: 4 <= scale < 7 (hide smallest hamlets)
|
||||
// Bucket 2: 3 <= scale < 4 (hide small villages)
|
||||
// Bucket 1: 2 <= scale < 3 (hide most towns)
|
||||
// Bucket 0: 1 <= scale < 2 (only capitals, main roads and sea routes)
|
||||
let bucket = 0;
|
||||
if (scale >= 7) bucket = 4;
|
||||
else if (scale >= 4) bucket = 3;
|
||||
else if (scale >= 3) bucket = 2;
|
||||
else if (scale >= 2) bucket = 1;
|
||||
|
||||
if (bucket === zoomVisibilityBucket) return; // nothing to update
|
||||
zoomVisibilityBucket = bucket;
|
||||
|
||||
// Safeguards for early lifecycle stages
|
||||
const burgsReady = !!pack?.burgs?.length;
|
||||
const routesLayerReady = !!routes?.size && routes.size();
|
||||
|
||||
// Compute population threshold for non-capital town visibility per bucket
|
||||
// Note: burg.population is a relative value in FMG; thresholds are heuristic
|
||||
let popThreshold = 0;
|
||||
switch (bucket) {
|
||||
case 4: // very close
|
||||
popThreshold = 0; // show all
|
||||
break;
|
||||
case 3: // close
|
||||
popThreshold = 1; // hide hamlets / very small villages
|
||||
break;
|
||||
case 2: // mid
|
||||
popThreshold = 2; // hide more small towns
|
||||
break;
|
||||
case 1: // far
|
||||
popThreshold = 5; // keep only larger towns (and all capitals)
|
||||
break;
|
||||
case 0: // very far
|
||||
default:
|
||||
popThreshold = Infinity; // only capitals
|
||||
break;
|
||||
}
|
||||
|
||||
if (burgsReady) {
|
||||
// Icons: capitals always visible
|
||||
const townIcons = burgIcons.select("#towns");
|
||||
const townAnchors = anchors.select("#towns");
|
||||
const cityIcons = burgIcons.select("#cities");
|
||||
const cityAnchors = anchors.select("#cities");
|
||||
|
||||
// Labels: capitals always visible; towns filtered
|
||||
const townLabels = burgLabels.select("#towns");
|
||||
const cityLabels = burgLabels.select("#cities");
|
||||
|
||||
// Show capitals consistently
|
||||
cityIcons.style("display", null);
|
||||
cityAnchors.style("display", null);
|
||||
cityLabels.style("display", null);
|
||||
|
||||
// Toggle towns by population threshold
|
||||
if (popThreshold === Infinity) {
|
||||
townIcons.style("display", "none");
|
||||
townAnchors.style("display", "none");
|
||||
townLabels.style("display", "none");
|
||||
} else if (popThreshold === 0) {
|
||||
townIcons.style("display", null);
|
||||
townAnchors.style("display", null);
|
||||
townLabels.style("display", null);
|
||||
} else {
|
||||
// For performance, bulk show groups, then hide specific small towns
|
||||
townIcons.style("display", null);
|
||||
townAnchors.style("display", null);
|
||||
townLabels.style("display", null);
|
||||
|
||||
// Hide individual small towns (icons, anchors, labels) below threshold
|
||||
const hideSmallTown = d => d && !d.capital && (d.population || 0) < popThreshold;
|
||||
|
||||
// Icons
|
||||
townIcons
|
||||
.selectAll("circle")
|
||||
.style("display", function () {
|
||||
const id = +this.getAttribute("data-id");
|
||||
return hideSmallTown(pack.burgs[id]) ? "none" : null;
|
||||
});
|
||||
// Anchors (for ports)
|
||||
townAnchors
|
||||
.selectAll("use")
|
||||
.style("display", function () {
|
||||
const id = +this.getAttribute("data-id");
|
||||
return hideSmallTown(pack.burgs[id]) ? "none" : null;
|
||||
});
|
||||
// Labels
|
||||
townLabels
|
||||
.selectAll("text")
|
||||
.style("display", function () {
|
||||
const id = +this.getAttribute("data-id");
|
||||
return hideSmallTown(pack.burgs[id]) ? "none" : null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Routes visibility: show fewer types when zoomed far out
|
||||
if (routesLayerReady) {
|
||||
// Trails (foot paths) drop first
|
||||
const showTrails = bucket >= 3; // show only at close zoom
|
||||
routes.select("#trails").style("display", showTrails ? null : "none");
|
||||
|
||||
// Roads (main / royal) remain at all zooms
|
||||
routes.select("#roads").style("display", null);
|
||||
|
||||
// Sea routes: keep visible at all zooms (treated as major routes)
|
||||
routes.select("#searoutes").style("display", null);
|
||||
|
||||
// Air routes: keep as-is based on layer toggle; do not alter here
|
||||
}
|
||||
}
|
||||
|
||||
// add drag to upload logic, pull request from @evyatron
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ function drawLayers() {
|
|||
if (layerIsOn("toggleRulers")) rulers.draw();
|
||||
// scale bar
|
||||
// vignette
|
||||
// apply zoom-based visibility after all layers rendered
|
||||
if (typeof invokeActiveZooming === "function") invokeActiveZooming();
|
||||
}
|
||||
|
||||
function toggleHeight(event) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue