Reuse player marker icons when removing and readding to map

This commit is contained in:
James Lyne 2022-02-06 12:29:43 +00:00
parent b3e593897b
commit b75d1022b7
2 changed files with 36 additions and 10 deletions

View File

@ -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<PlayerIconOptions> {
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<PlayerIconOptions> {
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<PlayerIconOptions> {
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<PlayerIconOptions> {
}
}
}
detach() {
if(this._container && this._container.parentNode) {
this._container = this._container.parentNode.removeChild(this._container);
}
}
}

View File

@ -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);
}