Refine map tile updates and enhance performance
- Updated tile freshness animation to reduce flicker and improve visual clarity. - Modified MapView component to optimize layer visibility handling and ensure proper map resizing on fullscreen toggle. - Increased tile buffer size in map initialization for better tile loading efficiency. - Implemented logic to limit tile updates to only visible tiles, enhancing rendering performance during map updates.
This commit is contained in:
@@ -9,17 +9,15 @@
|
|||||||
visibility: visible !important;
|
visibility: visible !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Brief highlight when a tile is updated via SSE (tile freshness indicator). */
|
/* Subtle highlight when a tile is updated via SSE (reduced intensity to limit flicker). */
|
||||||
@keyframes tile-fresh-glow {
|
@keyframes tile-fresh-glow {
|
||||||
0% {
|
0% {
|
||||||
filter: brightness(1.15);
|
opacity: 0.92;
|
||||||
box-shadow: 0 0 0 0 oklch(0.6 0.2 264 / 0.4);
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
filter: brightness(1);
|
opacity: 1;
|
||||||
box-shadow: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.leaflet-tile.tile-fresh {
|
.leaflet-tile.tile-fresh {
|
||||||
animation: tile-fresh-glow 0.6s ease-out;
|
animation: tile-fresh-glow 0.4s ease-out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -439,13 +439,21 @@ onMounted(async () => {
|
|||||||
;(mapInit.coordLayer.options as { visible?: boolean }).visible = v
|
;(mapInit.coordLayer.options as { visible?: boolean }).visible = v
|
||||||
mapInit.coordLayer.setOpacity(v ? 1 : 0)
|
mapInit.coordLayer.setOpacity(v ? 1 : 0)
|
||||||
mapInit.coordLayer.redraw?.()
|
mapInit.coordLayer.redraw?.()
|
||||||
if (v && leafletMap) {
|
if (v) mapInit.coordLayer.bringToFront?.()
|
||||||
mapInit.coordLayer.bringToFront?.()
|
|
||||||
leafletMap.invalidateSize()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => fullscreen.isFullscreen.value,
|
||||||
|
() => {
|
||||||
|
nextTick(() => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (leafletMap) leafletMap.invalidateSize()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
watch(mapLogic.state.hideMarkers, (v) => {
|
watch(mapLogic.state.hideMarkers, (v) => {
|
||||||
layersManager?.refreshMarkersVisibility(v)
|
layersManager?.refreshMarkersVisibility(v)
|
||||||
})
|
})
|
||||||
@@ -496,9 +504,6 @@ onMounted(async () => {
|
|||||||
|
|
||||||
leafletMap.on('moveend', () => mapLogic.updateDisplayCoords(leafletMap))
|
leafletMap.on('moveend', () => mapLogic.updateDisplayCoords(leafletMap))
|
||||||
mapLogic.updateDisplayCoords(leafletMap)
|
mapLogic.updateDisplayCoords(leafletMap)
|
||||||
leafletMap.on('zoomend', () => {
|
|
||||||
if (leafletMap) leafletMap.invalidateSize()
|
|
||||||
})
|
|
||||||
leafletMap.on('drag', () => {
|
leafletMap.on('drag', () => {
|
||||||
mapLogic.state.trackingCharacterId.value = -1
|
mapLogic.state.trackingCharacterId.value = -1
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export async function initLeafletMap(
|
|||||||
zoomReverse: true,
|
zoomReverse: true,
|
||||||
tileSize: TileSize,
|
tileSize: TileSize,
|
||||||
updateWhenIdle: true,
|
updateWhenIdle: true,
|
||||||
keepBuffer: 2,
|
keepBuffer: 4,
|
||||||
})
|
})
|
||||||
layer.map = initialMapId
|
layer.map = initialMapId
|
||||||
layer.invalidTile =
|
layer.invalidTile =
|
||||||
@@ -88,7 +88,7 @@ export async function initLeafletMap(
|
|||||||
tileSize: TileSize,
|
tileSize: TileSize,
|
||||||
opacity: 0.5,
|
opacity: 0.5,
|
||||||
updateWhenIdle: true,
|
updateWhenIdle: true,
|
||||||
keepBuffer: 2,
|
keepBuffer: 4,
|
||||||
})
|
})
|
||||||
overlayLayer.map = -1
|
overlayLayer.map = -1
|
||||||
overlayLayer.invalidTile =
|
overlayLayer.invalidTile =
|
||||||
|
|||||||
@@ -57,6 +57,21 @@ export function startMapUpdates(options: UseMapUpdatesOptions): UseMapUpdatesRet
|
|||||||
let batch: TileUpdate[] = []
|
let batch: TileUpdate[] = []
|
||||||
let batchScheduled = false
|
let batchScheduled = false
|
||||||
|
|
||||||
|
const VISIBLE_TILE_BUFFER = 1
|
||||||
|
|
||||||
|
function getVisibleTileBounds() {
|
||||||
|
const zoom = map.getZoom()
|
||||||
|
const px = map.getPixelBounds()
|
||||||
|
if (!px) return null
|
||||||
|
return {
|
||||||
|
zoom,
|
||||||
|
minX: Math.floor(px.min.x / TileSize) - VISIBLE_TILE_BUFFER,
|
||||||
|
maxX: Math.ceil(px.max.x / TileSize) + VISIBLE_TILE_BUFFER,
|
||||||
|
minY: Math.floor(px.min.y / TileSize) - VISIBLE_TILE_BUFFER,
|
||||||
|
maxY: Math.ceil(px.max.y / TileSize) + VISIBLE_TILE_BUFFER,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function applyBatch() {
|
function applyBatch() {
|
||||||
batchScheduled = false
|
batchScheduled = false
|
||||||
if (batch.length === 0) return
|
if (batch.length === 0) return
|
||||||
@@ -67,7 +82,14 @@ export function startMapUpdates(options: UseMapUpdatesOptions): UseMapUpdatesRet
|
|||||||
layer.cache[key] = u.T
|
layer.cache[key] = u.T
|
||||||
overlayLayer.cache[key] = u.T
|
overlayLayer.cache[key] = u.T
|
||||||
}
|
}
|
||||||
|
const visible = getVisibleTileBounds()
|
||||||
for (const u of updates) {
|
for (const u of updates) {
|
||||||
|
if (visible && u.Z !== visible.zoom) continue
|
||||||
|
if (
|
||||||
|
visible &&
|
||||||
|
(u.X < visible.minX || u.X > visible.maxX || u.Y < visible.minY || u.Y > visible.maxY)
|
||||||
|
)
|
||||||
|
continue
|
||||||
if (layer.map === u.M) layer.refresh(u.X, u.Y, u.Z)
|
if (layer.map === u.M) layer.refresh(u.X, u.Y, u.Z)
|
||||||
if (overlayLayer.map === u.M) overlayLayer.refresh(u.X, u.Y, u.Z)
|
if (overlayLayer.map === u.M) overlayLayer.refresh(u.X, u.Y, u.Z)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,12 +71,14 @@ export const SmartTileLayer = L.TileLayer.extend({
|
|||||||
|
|
||||||
const key = `${x}:${y}:${zoom}`
|
const key = `${x}:${y}:${zoom}`
|
||||||
const tile = this._tiles[key]
|
const tile = this._tiles[key]
|
||||||
if (tile?.el) {
|
if (!tile?.el) return
|
||||||
tile.el.src = this.getTrueTileUrl({ x, y }, z)
|
const newUrl = this.getTrueTileUrl({ x, y }, z)
|
||||||
tile.el.classList.add('tile-fresh')
|
if (tile.el.dataset.tileUrl === newUrl) return
|
||||||
const el = tile.el
|
tile.el.dataset.tileUrl = newUrl
|
||||||
setTimeout(() => el.classList.remove('tile-fresh'), 600)
|
tile.el.src = newUrl
|
||||||
}
|
tile.el.classList.add('tile-fresh')
|
||||||
|
const el = tile.el
|
||||||
|
setTimeout(() => el.classList.remove('tile-fresh'), 400)
|
||||||
},
|
},
|
||||||
}) as unknown as new (urlTemplate: string, options?: L.TileLayerOptions) => L.TileLayer & {
|
}) as unknown as new (urlTemplate: string, options?: L.TileLayerOptions) => L.TileLayer & {
|
||||||
cache: SmartTileLayerCache
|
cache: SmartTileLayerCache
|
||||||
|
|||||||
Reference in New Issue
Block a user