123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- var LeafletLabel = L.Class.extend({
- includes: L.Mixin.Events,
- options: {
- className: '',
- clickable: false,
- direction: 'right',
- noHide: false,
- offset: [12, -15], // 6 (width of the label triangle) + 6 (padding)
- opacity: 1,
- zoomAnimation: true
- },
- initialize: function (options, source) {
- L.setOptions(this, options);
- this._source = source;
- this._animated = L.Browser.any3d && this.options.zoomAnimation;
- this._isOpen = false;
- },
- onAdd: function (map) {
- this._map = map;
- this._pane = this.options.pane ? map._panes[this.options.pane] :
- this._source instanceof L.Marker ? map._panes.markerPane : map._panes.popupPane;
- if (!this._container) {
- this._initLayout();
- }
- this._pane.appendChild(this._container);
- this._initInteraction();
- this._update();
- this.setOpacity(this.options.opacity);
- map
- .on('moveend', this._onMoveEnd, this)
- .on('viewreset', this._onViewReset, this);
- if (this._animated) {
- map.on('zoomanim', this._zoomAnimation, this);
- }
- if (L.Browser.touch && !this.options.noHide) {
- L.DomEvent.on(this._container, 'click', this.close, this);
- map.on('click', this.close, this);
- }
- },
- onRemove: function (map) {
- this._pane.removeChild(this._container);
- map.off({
- zoomanim: this._zoomAnimation,
- moveend: this._onMoveEnd,
- viewreset: this._onViewReset
- }, this);
- this._removeInteraction();
- this._map = null;
- },
- setLatLng: function (latlng) {
- this._latlng = L.latLng(latlng);
- if (this._map) {
- this._updatePosition();
- }
- return this;
- },
- setContent: function (content) {
- // Backup previous content and store new content
- this._previousContent = this._content;
- this._content = content;
- this._updateContent();
- return this;
- },
- close: function () {
- var map = this._map;
- if (map) {
- if (L.Browser.touch && !this.options.noHide) {
- L.DomEvent.off(this._container, 'click', this.close);
- map.off('click', this.close, this);
- }
- map.removeLayer(this);
- }
- },
- updateZIndex: function (zIndex) {
- this._zIndex = zIndex;
- if (this._container && this._zIndex) {
- this._container.style.zIndex = zIndex;
- }
- },
- setOpacity: function (opacity) {
- this.options.opacity = opacity;
- if (this._container) {
- L.DomUtil.setOpacity(this._container, opacity);
- }
- },
- _initLayout: function () {
- this._container = L.DomUtil.create('div', 'leaflet-label ' + this.options.className + ' leaflet-zoom-animated');
- this.updateZIndex(this._zIndex);
- },
- _update: function () {
- if (!this._map) { return; }
- this._container.style.visibility = 'hidden';
- this._updateContent();
- this._updatePosition();
- this._container.style.visibility = '';
- },
- _updateContent: function () {
- if (!this._content || !this._map || this._prevContent === this._content) {
- return;
- }
- if (typeof this._content === 'string') {
- this._container.innerHTML = this._content;
- this._prevContent = this._content;
- this._labelWidth = this._container.offsetWidth;
- }
- },
- _updatePosition: function () {
- var pos = this._map.latLngToLayerPoint(this._latlng);
- this._setPosition(pos);
- },
- _setPosition: function (pos) {
- var map = this._map,
- container = this._container,
- centerPoint = map.latLngToContainerPoint(map.getCenter()),
- labelPoint = map.layerPointToContainerPoint(pos),
- direction = this.options.direction,
- labelWidth = this._labelWidth,
- offset = L.point(this.options.offset);
- // position to the right (right or auto & needs to)
- if (direction === 'right' || direction === 'auto' && labelPoint.x < centerPoint.x) {
- L.DomUtil.addClass(container, 'leaflet-label-right');
- L.DomUtil.removeClass(container, 'leaflet-label-left');
- pos = pos.add(offset);
- } else { // position to the left
- L.DomUtil.addClass(container, 'leaflet-label-left');
- L.DomUtil.removeClass(container, 'leaflet-label-right');
- pos = pos.add(L.point(-offset.x - labelWidth, offset.y));
- }
- L.DomUtil.setPosition(container, pos);
- },
- _zoomAnimation: function (opt) {
- var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
- this._setPosition(pos);
- },
- _onMoveEnd: function () {
- if (!this._animated || this.options.direction === 'auto') {
- this._updatePosition();
- }
- },
- _onViewReset: function (e) {
- /* if map resets hard, we must update the label */
- if (e && e.hard) {
- this._update();
- }
- },
- _initInteraction: function () {
- if (!this.options.clickable) { return; }
- var container = this._container,
- events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
- L.DomUtil.addClass(container, 'leaflet-clickable');
- L.DomEvent.on(container, 'click', this._onMouseClick, this);
- for (var i = 0; i < events.length; i++) {
- L.DomEvent.on(container, events[i], this._fireMouseEvent, this);
- }
- },
- _removeInteraction: function () {
- if (!this.options.clickable) { return; }
- var container = this._container,
- events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
- L.DomUtil.removeClass(container, 'leaflet-clickable');
- L.DomEvent.off(container, 'click', this._onMouseClick, this);
- for (var i = 0; i < events.length; i++) {
- L.DomEvent.off(container, events[i], this._fireMouseEvent, this);
- }
- },
- _onMouseClick: function (e) {
- if (this.hasEventListeners(e.type)) {
- L.DomEvent.stopPropagation(e);
- }
- this.fire(e.type, {
- originalEvent: e
- });
- },
- _fireMouseEvent: function (e) {
- this.fire(e.type, {
- originalEvent: e
- });
- // TODO proper custom event propagation
- // this line will always be called if marker is in a FeatureGroup
- if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
- L.DomEvent.preventDefault(e);
- }
- if (e.type !== 'mousedown') {
- L.DomEvent.stopPropagation(e);
- } else {
- L.DomEvent.preventDefault(e);
- }
- }
- });
|