From b75d1022b7dfbbe346bd1e0bf61797468b54a36f Mon Sep 17 00:00:00 2001 From: James Lyne Date: Sun, 6 Feb 2022 12:29:43 +0000 Subject: [PATCH] Reuse player marker icons when removing and readding to map --- src/leaflet/icon/PlayerIcon.ts | 27 +++++++++++++++++++-------- src/leaflet/marker/PlayerMarker.ts | 19 +++++++++++++++++-- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/leaflet/icon/PlayerIcon.ts b/src/leaflet/icon/PlayerIcon.ts index 18acea8..50beae9 100644 --- a/src/leaflet/icon/PlayerIcon.ts +++ b/src/leaflet/icon/PlayerIcon.ts @@ -17,7 +17,7 @@ * limitations under the License. */ -import {BaseIconOptions, DomUtil, Icon, Layer, LayerOptions, Util} from 'leaflet'; +import {BaseIconOptions, Icon, Layer, LayerOptions, Util} from 'leaflet'; import {getImagePixelSize, getMinecraftHead} from '@/util'; import defaultImage from '@/assets/images/player_face.png'; import {LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index"; @@ -57,9 +57,11 @@ export class PlayerIcon extends Layer implements Icon { this._player = player; } - createIcon(oldIcon: HTMLElement) { - if (oldIcon) { - DomUtil.remove(oldIcon); + createIcon() { + // Reuse detached icon if it exists + if (this._container) { + this.update(); + return this._container; } this._currentName = undefined; @@ -80,10 +82,7 @@ export class PlayerIcon extends Layer implements Icon { this._playerImage = playerImage.cloneNode() as HTMLImageElement; this._playerImage.height = this._playerImage.width = getImagePixelSize(this.options.imageSize); - getMinecraftHead(this._player, this.options.imageSize).then(head => { - this._playerImage!.src = head.src; - }).catch(() => {}); - + this.updateImage(); this._playerInfo.appendChild(this._playerImage); } @@ -126,6 +125,12 @@ export class PlayerIcon extends Layer implements Icon { return null; } + updateImage() { + getMinecraftHead(this._player, this.options.imageSize).then(head => { + this._playerImage!.src = head.src; + }).catch(() => {}); + } + update() { if(!this._container) { return; @@ -163,4 +168,10 @@ export class PlayerIcon extends Layer implements Icon { } } } + + detach() { + if(this._container && this._container.parentNode) { + this._container = this._container.parentNode.removeChild(this._container); + } + } } diff --git a/src/leaflet/marker/PlayerMarker.ts b/src/leaflet/marker/PlayerMarker.ts index 62bb7ce..8be478e 100644 --- a/src/leaflet/marker/PlayerMarker.ts +++ b/src/leaflet/marker/PlayerMarker.ts @@ -17,8 +17,9 @@ import {LatLng, MarkerOptions, Marker, Map, Util} from 'leaflet'; import {PlayerIcon} from "@/leaflet/icon/PlayerIcon"; import {LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index"; -import {watch} from "@vue/runtime-core"; -import {WatchStopHandle} from "vue"; +import {computed, watch} from "@vue/runtime-core"; +import {nextTick, WatchStopHandle} from "vue"; +import {useStore} from "@/store"; export interface PlayerMarkerOptions extends MarkerOptions { imageSize: LiveAtlasPlayerImageSize, @@ -30,10 +31,12 @@ export interface PlayerMarkerOptions extends MarkerOptions { export class PlayerMarker extends Marker { declare options: PlayerMarkerOptions; + declare _icon: HTMLElement | null; private readonly _PlayerIcon: PlayerIcon; private readonly _player: LiveAtlasPlayer; private _playerUnwatch?: WatchStopHandle; + private _imageUrlUnwatch?: WatchStopHandle; constructor(player: LiveAtlasPlayer, options: PlayerMarkerOptions) { super(new LatLng(0, 0), options); @@ -51,7 +54,11 @@ export class PlayerMarker extends Marker { } onAdd(map: Map) { + const imageUrl = computed(() => useStore().state.components.players.imageUrl); + this._playerUnwatch = watch(this._player, () => this._PlayerIcon.update(), {deep: true}); + this._imageUrlUnwatch = watch(imageUrl, () => nextTick(() => this._PlayerIcon.updateImage())); + return super.onAdd(map); } @@ -60,6 +67,14 @@ export class PlayerMarker extends Marker { this._playerUnwatch(); } + if(this._imageUrlUnwatch) { + this._imageUrlUnwatch(); + } + + if(this._icon) { + this._PlayerIcon.detach(); + } + return super.onRemove(map); }