Map: dark backdrop + reliable tile caching
Two fixes to the dark map + offline tiles: - Dark backdrop: body.dark-map also darkens .leaflet-container (was #ddd), so the light Leaflet background no longer flashes bright between/behind tiles while zooming or where a tile is missing. - Tile caching: createTile fetched the display <img> from the URL but cached via a SEPARATE fetch — on a flaky mobile link that second request often failed, so tiles showed but were never cached and re-zooming re-fetched them. Now one fetch caches and displays from the same blob, so every shown tile is cached. CSP already allows connect-src to the OSM tile host. Verified on device: container bg rgb(27,31,36) under dark map; IndexedDB tile cache populated.
This commit is contained in:
parent
5c23c4dda4
commit
375fb0a7ab
2 changed files with 26 additions and 19 deletions
|
|
@ -1149,6 +1149,9 @@ select {
|
|||
/* Dark map: invert ONLY the tile layer (overlays — track, route, roads, puck — keep
|
||||
their colours). User-tuned filter on OSM standard tiles. Applies to every Leaflet map. */
|
||||
body.dark-map .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(1.5); }
|
||||
/* Darken the map backdrop too, else the light Leaflet container (#ddd) flashes bright
|
||||
between/behind tiles while zooming or where a tile is missing. */
|
||||
body.dark-map .leaflet-container { background: #1b1f24; }
|
||||
/* Always-on compass needle: red half = North, grey = South. Rotates to point to real north.
|
||||
Top-RIGHT (zoom controls are top-left), below the status-bar safe area. */
|
||||
/* Position/direction puck (SVG divIcon) — no default leaflet-div-icon box. */
|
||||
|
|
|
|||
|
|
@ -130,29 +130,33 @@ TileCache.createLayer = function() {
|
|||
createTile: function(coords, done) {
|
||||
const tile = document.createElement("img");
|
||||
const key = `${coords.z}/${coords.x}/${coords.y}`;
|
||||
const url = `https://a.tile.openstreetmap.org/${key}.png`;
|
||||
const show = (blob) => { tile.src = URL.createObjectURL(blob); done(null, tile); };
|
||||
// Fetch ONCE: cache and display from the same response. The old code loaded the
|
||||
// display <img> from the URL and cached via a SEPARATE fetch — on a flaky mobile
|
||||
// link that second request often failed, so tiles showed but were never cached,
|
||||
// and re-zooming re-fetched them. One fetch → every shown tile is also cached.
|
||||
const fetchAndCache = () => {
|
||||
fetch(url).then(async resp => {
|
||||
if (!resp.ok) throw new Error("http " + resp.status);
|
||||
const blob = await resp.blob();
|
||||
putTile(key, blob).catch(() => {});
|
||||
show(blob);
|
||||
}).catch(() => {
|
||||
// fetch blocked/failed → last resort plain <img> (no caching)
|
||||
tile.src = url;
|
||||
tile.onload = () => done(null, tile);
|
||||
tile.onerror = () => done(null, tile);
|
||||
});
|
||||
};
|
||||
|
||||
getTile(key).then(blob => {
|
||||
if (blob) {
|
||||
tile.src = URL.createObjectURL(blob);
|
||||
done(null, tile);
|
||||
} else if (TileCache.offlineMode) {
|
||||
// Offline: show empty tile
|
||||
done(null, tile);
|
||||
} else {
|
||||
// Fetch from network
|
||||
tile.crossOrigin = "";
|
||||
tile.src = `https://a.tile.openstreetmap.org/${key}.png`;
|
||||
tile.onload = () => {
|
||||
fetch(tile.src).then(r => r.blob()).then(b => putTile(key, b)).catch(() => {});
|
||||
done(null, tile);
|
||||
};
|
||||
tile.onerror = () => done(null, tile);
|
||||
}
|
||||
if (blob) { show(blob); }
|
||||
else if (TileCache.offlineMode) { done(null, tile); } // offline + not cached → empty
|
||||
else { fetchAndCache(); }
|
||||
}).catch(() => {
|
||||
if (TileCache.offlineMode) { done(null, tile); return; }
|
||||
tile.src = `https://a.tile.openstreetmap.org/${key}.png`;
|
||||
tile.onload = () => done(null, tile);
|
||||
tile.onerror = () => done(null, tile);
|
||||
fetchAndCache();
|
||||
});
|
||||
|
||||
return tile;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue