Reuse player marker icons when removing and readding to map
This commit is contained in:
parent
b3e593897b
commit
b75d1022b7
@ -17,7 +17,7 @@
|
|||||||
* limitations under the License.
|
* 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 {getImagePixelSize, getMinecraftHead} from '@/util';
|
||||||
import defaultImage from '@/assets/images/player_face.png';
|
import defaultImage from '@/assets/images/player_face.png';
|
||||||
import {LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index";
|
import {LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index";
|
||||||
@ -57,9 +57,11 @@ export class PlayerIcon extends Layer implements Icon<PlayerIconOptions> {
|
|||||||
this._player = player;
|
this._player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
createIcon(oldIcon: HTMLElement) {
|
createIcon() {
|
||||||
if (oldIcon) {
|
// Reuse detached icon if it exists
|
||||||
DomUtil.remove(oldIcon);
|
if (this._container) {
|
||||||
|
this.update();
|
||||||
|
return this._container;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._currentName = undefined;
|
this._currentName = undefined;
|
||||||
@ -80,10 +82,7 @@ export class PlayerIcon extends Layer implements Icon<PlayerIconOptions> {
|
|||||||
this._playerImage = playerImage.cloneNode() as HTMLImageElement;
|
this._playerImage = playerImage.cloneNode() as HTMLImageElement;
|
||||||
this._playerImage.height = this._playerImage.width = getImagePixelSize(this.options.imageSize);
|
this._playerImage.height = this._playerImage.width = getImagePixelSize(this.options.imageSize);
|
||||||
|
|
||||||
getMinecraftHead(this._player, this.options.imageSize).then(head => {
|
this.updateImage();
|
||||||
this._playerImage!.src = head.src;
|
|
||||||
}).catch(() => {});
|
|
||||||
|
|
||||||
this._playerInfo.appendChild(this._playerImage);
|
this._playerInfo.appendChild(this._playerImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +125,12 @@ export class PlayerIcon extends Layer implements Icon<PlayerIconOptions> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateImage() {
|
||||||
|
getMinecraftHead(this._player, this.options.imageSize).then(head => {
|
||||||
|
this._playerImage!.src = head.src;
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
if(!this._container) {
|
if(!this._container) {
|
||||||
return;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
import {LatLng, MarkerOptions, Marker, Map, Util} from 'leaflet';
|
import {LatLng, MarkerOptions, Marker, Map, Util} from 'leaflet';
|
||||||
import {PlayerIcon} from "@/leaflet/icon/PlayerIcon";
|
import {PlayerIcon} from "@/leaflet/icon/PlayerIcon";
|
||||||
import {LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index";
|
import {LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index";
|
||||||
import {watch} from "@vue/runtime-core";
|
import {computed, watch} from "@vue/runtime-core";
|
||||||
import {WatchStopHandle} from "vue";
|
import {nextTick, WatchStopHandle} from "vue";
|
||||||
|
import {useStore} from "@/store";
|
||||||
|
|
||||||
export interface PlayerMarkerOptions extends MarkerOptions {
|
export interface PlayerMarkerOptions extends MarkerOptions {
|
||||||
imageSize: LiveAtlasPlayerImageSize,
|
imageSize: LiveAtlasPlayerImageSize,
|
||||||
@ -30,10 +31,12 @@ export interface PlayerMarkerOptions extends MarkerOptions {
|
|||||||
|
|
||||||
export class PlayerMarker extends Marker {
|
export class PlayerMarker extends Marker {
|
||||||
declare options: PlayerMarkerOptions;
|
declare options: PlayerMarkerOptions;
|
||||||
|
declare _icon: HTMLElement | null;
|
||||||
|
|
||||||
private readonly _PlayerIcon: PlayerIcon;
|
private readonly _PlayerIcon: PlayerIcon;
|
||||||
private readonly _player: LiveAtlasPlayer;
|
private readonly _player: LiveAtlasPlayer;
|
||||||
private _playerUnwatch?: WatchStopHandle;
|
private _playerUnwatch?: WatchStopHandle;
|
||||||
|
private _imageUrlUnwatch?: WatchStopHandle;
|
||||||
|
|
||||||
constructor(player: LiveAtlasPlayer, options: PlayerMarkerOptions) {
|
constructor(player: LiveAtlasPlayer, options: PlayerMarkerOptions) {
|
||||||
super(new LatLng(0, 0), options);
|
super(new LatLng(0, 0), options);
|
||||||
@ -51,7 +54,11 @@ export class PlayerMarker extends Marker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAdd(map: Map) {
|
onAdd(map: Map) {
|
||||||
|
const imageUrl = computed(() => useStore().state.components.players.imageUrl);
|
||||||
|
|
||||||
this._playerUnwatch = watch(this._player, () => this._PlayerIcon.update(), {deep: true});
|
this._playerUnwatch = watch(this._player, () => this._PlayerIcon.update(), {deep: true});
|
||||||
|
this._imageUrlUnwatch = watch(imageUrl, () => nextTick(() => this._PlayerIcon.updateImage()));
|
||||||
|
|
||||||
return super.onAdd(map);
|
return super.onAdd(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +67,14 @@ export class PlayerMarker extends Marker {
|
|||||||
this._playerUnwatch();
|
this._playerUnwatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this._imageUrlUnwatch) {
|
||||||
|
this._imageUrlUnwatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._icon) {
|
||||||
|
this._PlayerIcon.detach();
|
||||||
|
}
|
||||||
|
|
||||||
return super.onRemove(map);
|
return super.onRemove(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user