Marker refactoring

- Don't extend DivIcon as we don't use anything that class provides
- Update PlayerMarker icon using internal watch
- Remove unused panTo() PlayerMarker method
- Apply needed parts of _setIconStyles directly in GenericIcon's createIcon
This commit is contained in:
James Lyne 2021-09-01 17:38:42 +01:00
parent fb53ad195c
commit 77b9850ea9
4 changed files with 46 additions and 33 deletions

View File

@ -211,7 +211,6 @@ export default defineComponent({
this.marker.setLatLng(latLng);
this.chatBalloon.setLatLng(latLng);
this.marker.getIcon().update();
}
} else if(this.markerVisible) {
this.disableLayer();

View File

@ -17,14 +17,16 @@
* limitations under the License.
*/
import {DivIconOptions, PointExpression, Icon, DivIcon, DomUtil, point} from 'leaflet';
import {PointExpression, Icon, DomUtil, point, BaseIconOptions, PointTuple, Layer, LayerOptions, Util} from 'leaflet';
import {useStore} from "@/store";
export interface GenericIconOptions extends DivIconOptions {
export interface GenericIconOptions extends BaseIconOptions {
icon: string;
label: string;
isHtml?: boolean;
showLabel?: boolean;
iconSize: PointTuple;
className?: string;
}
const markerContainer: HTMLDivElement = document.createElement('div');
@ -36,17 +38,16 @@ markerIcon.className = 'marker__icon';
const markerLabel: HTMLSpanElement = document.createElement('span');
markerLabel.className = 'marker__label';
export class GenericIcon extends DivIcon {
static defaultOptions: GenericIconOptions = {
icon: 'default',
label: '',
iconSize: [16, 16],
isHtml: false,
className: '',
};
const defaultOptions: GenericIconOptions = {
icon: 'default',
label: '',
iconSize: [16, 16],
isHtml: false,
className: '',
}
export class GenericIcon extends Layer implements Icon<GenericIconOptions> {
declare options: GenericIconOptions;
private _image?: HTMLImageElement;
private _label?: HTMLSpanElement;
private _container?: HTMLDivElement;
@ -56,7 +57,8 @@ export class GenericIcon extends DivIcon {
};
constructor(options: GenericIconOptions) {
super(Object.assign(GenericIcon.defaultOptions, options));
super(options as LayerOptions);
Util.setOptions(this, Object.assign(defaultOptions, options));
}
createIcon(oldIcon: HTMLElement) {
@ -74,11 +76,11 @@ export class GenericIcon extends DivIcon {
this._image.height = size.y;
this._image.src = url;
// @ts-ignore
super._setIconStyles(div, 'icon');
div.appendChild(this._image);
div.classList.add('marker');
div.style.marginLeft = `${-(size.x / 2)}px`;
div.style.marginTop = `${-(size.y / 2)}px`;
div.style.height = `${size.y}px`;
div.classList.add('marker', 'leaflet-marker-icon');
if(this.options.className) {
div.classList.add(this.options.className);
@ -92,6 +94,11 @@ export class GenericIcon extends DivIcon {
return div;
}
createShadow(oldIcon?: HTMLElement): HTMLElement {
// @ts-ignore - Typings are wrong here, can return null
return null;
}
createLabel() {
if(!this._container || this._labelCreated) {
return;

View File

@ -17,7 +17,7 @@
* limitations under the License.
*/
import {MarkerOptions, DivIcon, DomUtil} from 'leaflet';
import {BaseIconOptions, DomUtil, Icon, Layer, LayerOptions, Util} from 'leaflet';
import {getMinecraftHead} from '@/util';
import playerImage from '@/assets/images/player_face.png';
import {LiveAtlasPlayer} from "@/index";
@ -41,14 +41,14 @@ bodyImage.width = 32;
noSkinImage.src = smallImage.src = largeImage.src = bodyImage.src = playerImage;
noSkinImage.className = smallImage.className = largeImage.className = bodyImage.className = 'player__icon';
export interface PlayerIconOptions extends MarkerOptions {
export interface PlayerIconOptions extends BaseIconOptions {
smallFace: boolean,
showSkinFace: boolean,
showBody: boolean,
showHealth: boolean,
}
export class PlayerIcon extends DivIcon {
export class PlayerIcon extends Layer implements Icon<PlayerIconOptions> {
declare options: PlayerIconOptions;
private readonly _player: LiveAtlasPlayer;
@ -65,7 +65,8 @@ export class PlayerIcon extends DivIcon {
private _playerArmorBar?: HTMLDivElement;
constructor(player: LiveAtlasPlayer, options: PlayerIconOptions) {
super(options);
super(options as LayerOptions);
Util.setOptions(this, options);
this._player = player;
}
@ -145,6 +146,11 @@ export class PlayerIcon extends DivIcon {
return this._container;
}
createShadow(oldIcon?: HTMLElement): HTMLElement {
// @ts-ignore - Typings are wrong here, can return null
return null;
}
update() {
if(!this._container) {
return;

View File

@ -17,6 +17,8 @@
import {LatLng, MarkerOptions, Marker, Util} from 'leaflet';
import {PlayerIcon} from "@/leaflet/icon/PlayerIcon";
import {LiveAtlasPlayer} from "@/index";
import {watch} from "@vue/runtime-core";
import {WatchStopHandle} from "vue";
export interface PlayerMarkerOptions extends MarkerOptions {
smallFace: boolean,
@ -28,14 +30,15 @@ export interface PlayerMarkerOptions extends MarkerOptions {
export class PlayerMarker extends Marker {
declare options: PlayerMarkerOptions;
private _player: LiveAtlasPlayer;
private readonly _PlayerIcon: PlayerIcon;
private readonly _player: LiveAtlasPlayer;
private _playerUnwatch?: WatchStopHandle;
constructor(player: LiveAtlasPlayer, options: PlayerMarkerOptions) {
super(new LatLng(0, 0), options);
this._player = player;
options.draggable = false;
options.icon = new PlayerIcon(player, {
this._PlayerIcon = options.icon = new PlayerIcon(player, {
smallFace: options.smallFace,
showSkinFace: options.showSkinFace,
showBody: options.showBody,
@ -45,19 +48,17 @@ export class PlayerMarker extends Marker {
Util.setOptions(this, options);
}
getIcon(): PlayerIcon {
return this.options.icon as PlayerIcon;
onAdd(map: Map) {
this._playerUnwatch = watch(this._player, () => this._PlayerIcon.update(), {deep: true});
return super.onAdd(map);
}
panTo() {
if (!this._map) {
return;
onRemove(map: Map): this {
if(this._playerUnwatch) {
this._playerUnwatch();
}
this._map.panTo(this.getLatLng(), {
animate: false,
noMoveStart: true,
});
return super.onRemove(map);
}
// noinspection JSUnusedGlobalSymbols