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.marker.setLatLng(latLng);
this.chatBalloon.setLatLng(latLng); this.chatBalloon.setLatLng(latLng);
this.marker.getIcon().update();
} }
} else if(this.markerVisible) { } else if(this.markerVisible) {
this.disableLayer(); this.disableLayer();

View File

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

View File

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

View File

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