2020-12-16 16:54:41 +00:00
|
|
|
/*
|
2021-07-25 14:12:40 +00:00
|
|
|
* Copyright 2021 James Lyne
|
2020-12-16 16:54:41 +00:00
|
|
|
*
|
|
|
|
* Some portions of this file were taken from https://github.com/webbukkit/dynmap.
|
|
|
|
* These portions are Copyright 2020 Dynmap Contributors.
|
|
|
|
*
|
2021-07-25 14:12:40 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2020-12-16 16:54:41 +00:00
|
|
|
*
|
2021-07-25 14:12:40 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2020-12-16 16:54:41 +00:00
|
|
|
*
|
2021-07-25 14:12:40 +00:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2020-12-16 16:54:41 +00:00
|
|
|
*/
|
|
|
|
|
2020-12-12 22:04:56 +00:00
|
|
|
import {DivIconOptions, PointExpression, Icon, DivIcon, DomUtil, point} from 'leaflet';
|
2021-05-17 02:39:25 +00:00
|
|
|
import {useStore} from "@/store";
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2021-07-23 21:28:06 +00:00
|
|
|
export interface GenericIconOptions extends DivIconOptions {
|
2020-12-01 23:20:38 +00:00
|
|
|
icon: string;
|
|
|
|
label: string;
|
|
|
|
isHtml?: boolean;
|
2021-05-15 19:25:03 +00:00
|
|
|
showLabel?: boolean;
|
2020-12-01 23:20:38 +00:00
|
|
|
}
|
|
|
|
|
2020-12-14 00:27:49 +00:00
|
|
|
const markerContainer: HTMLDivElement = document.createElement('div');
|
|
|
|
markerContainer.className = 'marker';
|
|
|
|
|
|
|
|
const markerIcon: HTMLImageElement = document.createElement('img');
|
|
|
|
markerIcon.className = 'marker__icon';
|
|
|
|
|
|
|
|
const markerLabel: HTMLSpanElement = document.createElement('span');
|
|
|
|
markerLabel.className = 'marker__label';
|
|
|
|
|
2021-07-23 21:28:06 +00:00
|
|
|
export class GenericIcon extends DivIcon {
|
|
|
|
static defaultOptions: GenericIconOptions = {
|
2020-12-01 23:20:38 +00:00
|
|
|
icon: 'default',
|
|
|
|
label: '',
|
2020-12-10 02:21:42 +00:00
|
|
|
iconSize: [16, 16],
|
2020-12-01 23:20:38 +00:00
|
|
|
isHtml: false,
|
|
|
|
className: '',
|
|
|
|
};
|
2020-12-10 02:21:42 +00:00
|
|
|
|
2021-08-26 20:40:54 +00:00
|
|
|
declare options: GenericIconOptions;
|
2021-07-29 16:46:11 +00:00
|
|
|
|
|
|
|
private _image?: HTMLImageElement;
|
|
|
|
private _label?: HTMLSpanElement;
|
|
|
|
private _container?: HTMLDivElement;
|
|
|
|
private _labelCreated: boolean = false;
|
|
|
|
private _onHover: EventListener = () => {
|
|
|
|
this.createLabel();
|
|
|
|
};
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2021-07-23 21:28:06 +00:00
|
|
|
constructor(options: GenericIconOptions) {
|
|
|
|
super(Object.assign(GenericIcon.defaultOptions, options));
|
2020-12-01 23:20:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
createIcon(oldIcon: HTMLElement) {
|
|
|
|
if (oldIcon) {
|
2020-12-12 22:04:56 +00:00
|
|
|
DomUtil.remove(oldIcon);
|
2020-12-01 23:20:38 +00:00
|
|
|
}
|
|
|
|
|
2020-12-14 00:27:49 +00:00
|
|
|
const div = markerContainer.cloneNode(false) as HTMLDivElement,
|
2021-07-25 00:57:59 +00:00
|
|
|
url = useStore().state.currentMapProvider!.getMarkerIconUrl(this.options.icon),
|
2020-12-12 22:04:56 +00:00
|
|
|
size = point(this.options.iconSize as PointExpression);
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2020-12-18 18:01:37 +00:00
|
|
|
this._image = markerIcon.cloneNode(false) as HTMLImageElement;
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2020-12-18 18:01:37 +00:00
|
|
|
this._image.width = size.x;
|
|
|
|
this._image.height = size.y;
|
|
|
|
this._image.src = url;
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2020-12-10 02:21:42 +00:00
|
|
|
// @ts-ignore
|
2021-08-31 15:41:11 +00:00
|
|
|
super._setIconStyles(div, 'icon');
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2020-12-18 18:01:37 +00:00
|
|
|
div.appendChild(this._image);
|
2020-12-10 02:21:42 +00:00
|
|
|
div.classList.add('marker');
|
|
|
|
|
|
|
|
if(this.options.className) {
|
|
|
|
div.classList.add(this.options.className);
|
|
|
|
}
|
2020-12-01 23:20:38 +00:00
|
|
|
|
2021-07-29 16:46:11 +00:00
|
|
|
//Create label lazily on hover
|
|
|
|
this._image.addEventListener('mouseover', this._onHover);
|
|
|
|
|
|
|
|
this._container = div;
|
|
|
|
|
2020-12-10 02:21:42 +00:00
|
|
|
return div;
|
2020-12-01 23:20:38 +00:00
|
|
|
}
|
2020-12-18 18:01:37 +00:00
|
|
|
|
2021-07-29 16:46:11 +00:00
|
|
|
createLabel() {
|
|
|
|
if(!this._container || this._labelCreated) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._image?.removeEventListener('mouseover', this._onHover);
|
|
|
|
|
|
|
|
const size = point(this.options.iconSize as PointExpression),
|
|
|
|
sizeClass = [size.x, size.y].join('x');
|
|
|
|
|
|
|
|
this._label = markerLabel.cloneNode(false) as HTMLSpanElement;
|
|
|
|
|
|
|
|
this._label.classList.add(/*'markerName_' + set.id,*/ `marker__label--${sizeClass}`);
|
|
|
|
|
|
|
|
if (this.options.isHtml) {
|
|
|
|
this._label.innerHTML = this.options.label;
|
|
|
|
} else {
|
|
|
|
this._label.textContent = this.options.label;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._container!.appendChild(this._label);
|
|
|
|
this._labelCreated = true;
|
|
|
|
}
|
|
|
|
|
2021-08-16 03:17:59 +00:00
|
|
|
removeLabel() {
|
|
|
|
if(!this._container || !this._labelCreated) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._label!.remove();
|
|
|
|
this._label = undefined;
|
|
|
|
this._labelCreated = false;
|
|
|
|
}
|
|
|
|
|
2021-07-23 21:28:06 +00:00
|
|
|
update(options: GenericIconOptions) {
|
2020-12-31 22:38:58 +00:00
|
|
|
if(this._image && options.icon !== this.options.icon) {
|
2021-07-25 00:57:59 +00:00
|
|
|
this._image!.src = useStore().state.currentMapProvider!.getMarkerIconUrl(this.options.icon);
|
2020-12-18 18:01:37 +00:00
|
|
|
this.options.icon = options.icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
const iconSize = point(options.iconSize || [16, 16] as PointExpression),
|
|
|
|
oldSize = point(this.options.iconSize as PointExpression);
|
|
|
|
|
2020-12-31 22:38:58 +00:00
|
|
|
if(this._image && (iconSize.x !== oldSize.x || iconSize.y !== oldSize.y)) {
|
2020-12-18 18:01:37 +00:00
|
|
|
this._image!.width = iconSize.x;
|
|
|
|
this._image!.height = iconSize.y;
|
|
|
|
this.options.iconSize = options.iconSize;
|
|
|
|
}
|
|
|
|
|
2020-12-31 22:38:58 +00:00
|
|
|
if(this._label && (options.label !== this.options.label || options.isHtml !== this.options.isHtml)) {
|
2020-12-18 18:01:37 +00:00
|
|
|
if (options.isHtml) {
|
|
|
|
this._label!.innerHTML = options.label;
|
|
|
|
} else {
|
|
|
|
this._label!.textContent = options.label;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.options.isHtml = options.isHtml;
|
|
|
|
this.options.label = options.label;
|
|
|
|
}
|
|
|
|
}
|
2020-12-01 23:20:38 +00:00
|
|
|
}
|