Skip to content
Merged

Minimap #1389

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions public/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,15 @@ function zoomRaf() {
}

if (didScaleChange) {
postZoom();
invokeActiveZooming();
drawScaleBar(scaleBar, scale);
fitScaleBar(scaleBar, svgWidth, svgHeight);
}
})
}

const postZoom = () => {
invokeActiveZooming();
drawScaleBar(scaleBar, scale);
fitScaleBar(scaleBar, svgWidth, svgHeight);
if (didPositionChange || didScaleChange) {
window.updateMinimap && updateMinimap();
}
});
}

const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomRaf);
Expand Down
133 changes: 133 additions & 0 deletions public/modules/ui/minimap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
"use strict";

let minimapInitialized = false;

export function openMinimapDialog() {
closeDialogs("#minimap, .stable");
ensureMinimapStyles();
ensureMinimapMarkup();

updateMinimap();

$("#minimap").dialog({
title: "Minimap",
resizable: false,
width: "auto",
position: {my: "left bottom", at: "left+10 bottom-25", of: "svg", collision: "fit"},
open: function () {
$(this).parent().addClass("minimap-dialog");
},
close: function () {
$(this).dialog("destroy");
}
});
}

function ensureMinimapStyles() {
if (byId("minimapStyles")) return;

const style = document.createElement("style");
style.id = "minimapStyles";
style.textContent = /* css */ `
.minimap-dialog .ui-dialog-content {
padding: 0 !important;
overflow: hidden;
}

#minimap {
padding: 0 !important;
background: transparent;
}

#minimapViewportWrap {
position: relative;
width: 20em;
border: 0;
}

#minimapSurface {
display: block;
width: 100%;
height: auto;
cursor: crosshair;
}

#minimapMapUse {
pointer-events: none;
}

#minimapViewport {
fill: rgba(190, 255, 137, 0.1);
stroke: #624954;
stroke-width: 1;
stroke-dasharray: 4;
vector-effect: non-scaling-stroke;
pointer-events: none;
}
`;

document.head.append(style);
}

function ensureMinimapMarkup() {
if (minimapInitialized) return;

const container = byId("minimapContent");
if (!container) return;

minimapInitialized = true;
container.innerHTML = /* html */ `
<div id="minimapViewportWrap">
<svg id="minimapSurface" preserveAspectRatio="xMidYMid meet" aria-label="Map minimap">
<use id="minimapMapUse" href="#viewbox"></use>
<rect id="minimapViewport"></rect>
</svg>
</div>
`;

byId("minimapSurface")?.addEventListener("click", minimapClickToPan);
window.updateMinimap = updateMinimap;
}

function minimapClickToPan(event) {
const minimap = byId("minimapSurface");
if (!minimap) return;

const point = minimap.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;

const ctm = minimap.getScreenCTM();
if (!ctm) return;

const svgPoint = point.matrixTransform(ctm.inverse());
const x = minmax(svgPoint.x, 0, graphWidth);
const y = minmax(svgPoint.y, 0, graphHeight);
zoomTo(x, y, scale, 450);
}

function updateMinimap() {
const minimap = byId("minimapSurface");
const viewport = byId("minimapViewport");
const mapUse = byId("minimapMapUse");
if (!minimap || !viewport || !mapUse) return;

minimap.setAttribute("viewBox", `0 0 ${graphWidth} ${graphHeight}`);

// #viewbox already has the current transform; invert it in minimap to show the whole world map.
const inverseScale = scale ? 1 / scale : 1;
mapUse.setAttribute(
"transform",
`translate(${rn(-viewX * inverseScale, 3)} ${rn(-viewY * inverseScale, 3)}) scale(${rn(inverseScale, 6)})`
);

const left = Math.max(0, -viewX * inverseScale);
const top = Math.max(0, -viewY * inverseScale);
const right = Math.min(graphWidth, left + svgWidth * inverseScale);
const bottom = Math.min(graphHeight, top + svgHeight * inverseScale);

viewport.setAttribute("x", rn(left, 3));
viewport.setAttribute("y", rn(top, 3));
viewport.setAttribute("width", rn(Math.max(0, right - left), 3));
viewport.setAttribute("height", rn(Math.max(0, bottom - top), 3));
}
14 changes: 10 additions & 4 deletions public/modules/ui/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ toolsContent.addEventListener("click", function (event) {
else if (button === "overviewMilitaryButton") overviewMilitary();
else if (button === "overviewMarkersButton") overviewMarkers();
else if (button === "overviewCellsButton") viewCellDetails();
else if (button === "openMinimapButton") openMinimap();

// click on Regenerate buttons
if (event.target.parentNode.id === "regenerateFeature") {
Expand Down Expand Up @@ -327,8 +328,8 @@ function recreateStates() {
const type = nomadic
? "Nomadic"
: pack.cultures[culture].type === "Nomadic"
? "Generic"
: pack.cultures[culture].type;
? "Generic"
: pack.cultures[culture].type;
const expansionism = rn(Math.random() * byId("sizeVariety").value + 1, 1);

const cultureType = pack.cultures[culture].type;
Expand Down Expand Up @@ -898,8 +899,8 @@ function configMarkersGeneration() {
<td><input class="type" value="${type}" /></td>
<td style="position: relative">
<img class="image" src="${isExternal ? icon : ""}" ${
isExternal ? "" : "hidden"
} style="width:1.2em; height:1.2em; vertical-align: middle;">
isExternal ? "" : "hidden"
} style="width:1.2em; height:1.2em; vertical-align: middle;">
<span class="emoji" style="font-size:1.2em">${isExternal ? "" : icon}</span>
<button class="changeIcon icon-pencil"></button>
</td>
Expand Down Expand Up @@ -987,3 +988,8 @@ async function overviewCharts() {
const Overview = await import("../dynamic/overview/charts-overview.js?v=1.99.00");
Overview.open();
}

async function openMinimap() {
const Minimap = await import("./minimap.js?v=1.99.00");
Minimap.openMinimapDialog();
}
7 changes: 7 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2269,6 +2269,9 @@
>
Charts
</button>
<button id="openMinimapButton" data-tip="Click to open minimap overview. Click minimap to center view">
Minimap
</button>
</div>

<div class="separator">Create</div>
Expand Down Expand Up @@ -6004,6 +6007,10 @@
</div>
</div>

<div id="minimap" style="display: none" class="dialog stable">
<div id="minimapContent"></div>
</div>

<div id="options3d" class="dialog stable" style="display: none">
<div id="options3dMesh" style="display: none">
<div data-tip="Set map rotation speed. Set to 0 is you want to toggle off the rotation">
Expand Down
Loading