Enhance map updates and component performance

- Updated API documentation to clarify the initial data message structure for real-time tile updates.
- Modified MapView component to load configuration and user data in parallel, improving map loading speed.
- Implemented asynchronous loading for markers after the map is visible, enhancing user experience.
- Introduced batching for tile updates to optimize rendering performance during map updates.
- Refactored character and marker creation functions to utilize dynamic Leaflet imports, improving modularity.
This commit is contained in:
2026-03-01 17:30:48 +03:00
parent 7bdaa6bfcc
commit 49af08c13f
9 changed files with 120 additions and 75 deletions

View File

@@ -1,5 +1,7 @@
import type L from 'leaflet'
import { HnHMaxZoom } from '~/lib/LeafletCustomTypes'
import * as L from 'leaflet'
export type LeafletApi = typeof import('leaflet')
/** SVG data URL for character marker icon (teal pin, bottom-center anchor). */
const CHARACTER_ICON_URL =
@@ -11,12 +13,14 @@ const CHARACTER_ICON_URL =
'</svg>'
)
const CHARACTER_ICON = new L.Icon({
iconUrl: CHARACTER_ICON_URL,
iconSize: [24, 32],
iconAnchor: [12, 32],
popupAnchor: [0, -32],
})
function createCharacterIcon(L: LeafletApi): L.Icon {
return new L.Icon({
iconUrl: CHARACTER_ICON_URL,
iconSize: [24, 32],
iconAnchor: [12, 32],
popupAnchor: [0, -32],
})
}
export interface CharacterData {
name: string
@@ -47,9 +51,10 @@ export interface MapCharacter {
setClickCallback: (callback: (e: L.LeafletMouseEvent) => void) => void
}
export function createCharacter(data: CharacterData): MapCharacter {
export function createCharacter(data: CharacterData, L: LeafletApi): MapCharacter {
let leafletMarker: L.Marker | null = null
let onClick: ((e: L.LeafletMouseEvent) => void) | null = null
const characterIcon = createCharacterIcon(L)
const character: MapCharacter = {
id: data.id,
@@ -75,7 +80,7 @@ export function createCharacter(data: CharacterData): MapCharacter {
add(mapview: CharacterMapViewRef): void {
if (character.map === mapview.mapid) {
const position = mapview.map.unproject([character.position.x, character.position.y], HnHMaxZoom)
leafletMarker = L.marker(position, { icon: CHARACTER_ICON, title: character.name })
leafletMarker = L.marker(position, { icon: characterIcon, title: character.name })
leafletMarker.on('click', (e: L.LeafletMouseEvent) => {
if (onClick) onClick(e)
})