Skip to content
Merged
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
28 changes: 22 additions & 6 deletions frontend/app/components/map/MapCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ function paintToolCursor(tool: UseMapPaintResult["tool"]): string {
* light rim `rimPx` screen pixels wide. The overlay sits inside the scaled
* map, so the rim is sized in map pixels divided by the scale to stay
* constant on screen. Hover gets a thin rim, the region whose details are
* open a thicker one; both stand down mid-gesture (`.map-selected-region`).
* open a thicker one. Mid-gesture the scale runs ahead of React, so the
* viewport writes it into `--map-rim-scale` on each `.map-selected-region`
* (see `setLiveRimScale`) and the rim keeps its width through a zoom.
*/
function regionHighlightStyle(
displayScale: number,
Expand All @@ -115,19 +117,32 @@ function regionHighlightStyle(
// Unfiltered, it still stands out: drawn again over its own colour, and,
// when selected, over the faded rest of the world.
if (!mapFiltersSupportedHere()) return {};
const px = displayScale > 0 ? rimPx / displayScale : 0;
if (!(displayScale > 0)) return {};
const px = `calc(${rimPx}px / var(--map-rim-scale))`;
const rim = `rgb(232 228 217 / ${rimAlpha})`;
return {
["--map-rim-scale" as string]: displayScale,
filter: [
"brightness(1.18) saturate(1.08)",
`drop-shadow(${px}px 0 0 ${rim})`,
`drop-shadow(-${px}px 0 0 ${rim})`,
`drop-shadow(0 ${px}px 0 ${rim})`,
`drop-shadow(0 -${px}px 0 ${rim})`,
`drop-shadow(${px} 0 0 ${rim})`,
`drop-shadow(calc(-1 * ${px}) 0 0 ${rim})`,
`drop-shadow(0 ${px} 0 ${rim})`,
`drop-shadow(0 calc(-1 * ${px}) 0 ${rim})`,
].join(" "),
};
}

/**
* Size the highlight rims under `content` for the scale on screen now. React
* writes the same value once the gesture settles, so nothing is left behind.
*/
function setLiveRimScale(content: HTMLElement | null, displayScale: number) {
if (!content || !(displayScale > 0)) return;
for (const element of content.querySelectorAll<HTMLElement>(".map-selected-region")) {
element.style.setProperty("--map-rim-scale", String(displayScale));
}
}

/**
* What the map is focused on: a selected region, or a realm opened to show
* its subjects. Every other region's colour fades; the focus keeps its own,
Expand Down Expand Up @@ -463,6 +478,7 @@ export default function MapCanvas({
// Mid-gesture the transform runs ahead of React; keep hover picking on
// what is actually on screen.
onLiveTransform: (live) => {
setLiveRimScale(viewport.contentRef.current, live.displayScale);
if (!viewportCoordsRef?.current) return;
viewportCoordsRef.current.displayScale = live.displayScale;
viewportCoordsRef.current.translateX = live.translateX;
Expand Down
5 changes: 1 addition & 4 deletions frontend/app/hooks/useMapViewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ export function useMapViewport({
}
if (!liveActiveRef.current) return;
liveActiveRef.current = false;
contentRef.current?.removeAttribute("data-gesturing");
setTransform(transformRef.current);
}, []);

Expand All @@ -275,9 +274,7 @@ export function useMapViewport({
);
// No `will-change` here: on a 6400 px layer it makes the browser
// rasterise one enormous texture, which measured slower than letting it
// re-tile. `data-gesturing` lets costly effects (the selection's
// outline filter) stand down until the map settles.
content.setAttribute("data-gesturing", "");
// re-tile.
content.style.transition = "none";
// A drag only moves the map: like the resting position (see below) it
// sits on whole device pixels, or every tile edge straddles a pixel and
Expand Down
6 changes: 0 additions & 6 deletions frontend/app/internal/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,6 @@ html.map-fullscreen textarea {
overflow: hidden;
}

/* The selection's outline is a stack of drop-shadow filters, redrawn at
* every scale; while the map is being zoomed or dragged it stands down. */
[data-gesturing] .map-selected-region {
filter: none !important;
}

/* An in-text link to another realm or place. */
.map-link {
color: var(--tfmc-cream);
Expand Down