Add L.Label related documentation

This commit is contained in:
Yohan Boniface 2016-05-06 15:00:01 +02:00
parent 737137634e
commit 4a9140e6b1
10 changed files with 158 additions and 62 deletions

View File

@ -7,6 +7,7 @@ This file just defines the order of the classes in the docs.
@class Marker
@class Popup
@class Label
@class TileLayer
@class TileLayer.WMS

View File

@ -43,6 +43,7 @@
<ul>
<li><a href="#marker">Marker</a></li>
<li><a href="#popup">Popup</a></li>
<li><a href="#label">Label</a></li>
</ul>
<h4>Raster Layers</h4>
<ul>
@ -313,4 +314,4 @@
</style>
</body></html>
</body></html>

View File

@ -31,25 +31,25 @@
var map = L.map('map').setView(center, 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.polygon([[41.21, 9.42], [41.22, 9.40], [41.23, 9.40]]).addTo(map).bindLabel('Default centered polygon label');
L.polygon([[41.20, 9.41], [41.20, 9.39], [41.21, 9.40]]).addTo(map).bindLabel('Polygon label following mouse', {followMouse: true});
L.polygon([[41.18, 9.42], [41.17, 9.40], [41.19, 9.38]]).addTo(map).bindLabel('Permanent polygon label', {static: true});
L.polygon([[41.20, 9.41], [41.20, 9.39], [41.21, 9.40]]).addTo(map).bindLabel('Polygon label following mouse', {sticky: true});
L.polygon([[41.18, 9.42], [41.17, 9.40], [41.19, 9.38]]).addTo(map).bindLabel('Permanent polygon label', {permanent: true});
L.marker([41.20, 9.4307]).addTo(map).bindLabel('label on the left', {direction: 'left'});
L.marker([41.206, 9.44]).addTo(map).bindLabel('click me, I have a popup', {static: true, interactive: true}).bindPopup('See?');
L.circleMarker([41.206, 9.48], {color: "Chocolate", radius: 12}).addTo(map).bindLabel( "Hello Left World", {direction: 'left'});
L.circleMarker([41.20, 9.50], {color: "Chocolate", radius: 12}).addTo(map).bindLabel( "Hello top World", {direction: 'top', static: true});
L.marker([41.206, 9.44]).addTo(map).bindLabel('click me, I have a popup', {permanent: true, interactive: true}).bindPopup('See?');
L.circleMarker([41.206, 9.48], {color: 'Chocolate', radius: 12}).addTo(map).bindLabel('Hello Left World', {direction: 'left'});
L.circleMarker([41.20, 9.50], {color: 'Chocolate', radius: 12}).addTo(map).bindLabel('Hello top World', {direction: 'top', permanent: true});
var icon = L.divIcon({
className: 'my-div-icon',
html: '<p>A div icon</p>',
iconSize: [50, 50],
iconSize: [50, 50]
});
L.marker([41.22, 9.48], {icon: icon}).addTo(map).bindLabel('A div icon label following mouse', {followMouse: true, direction: 'auto'});
L.marker([41.22, 9.48], {icon: icon}).addTo(map).bindLabel('A div icon label following mouse', {sticky: true, direction: 'auto'});
L.marker([41.23, 9.47], {icon: icon}).addTo(map).bindLabel('A div icon label');
L.marker([41.23, 9.42], {draggable: true}).addTo(map).bindLabel('Draggable marker label', {static: true, direction: 'auto'});
L.marker([41.19, 9.45]).addTo(map).bindLabel('Clickable marker label', {static: true, interactive: true}).on('click', function () { alert('clicked!'); });
L.marker([41.23, 9.42], {draggable: true}).addTo(map).bindLabel('Draggable marker label', {permanent: true, direction: 'auto'});
L.marker([41.19, 9.45]).addTo(map).bindLabel('Clickable marker label', {permanent: true, interactive: true}).on('click', function () { alert('clicked!'); });
var marker1 = L.marker([41.18, 9.45], {description: 'Marker 1'});
var marker2 = L.marker([41.18, 9.46], {description: 'Marker 2'});
@ -57,10 +57,10 @@
group.bindLabel(function (layer) {
return 'Group label: ' + layer.options.description;
}, {opacity: 0.7});
L.marker([41.18, 9.35]).addTo(map).bindLabel('Top label is top', {static: true, direction: 'top'});
L.marker([41.173, 9.37]).addTo(map).bindLabel('Bottom label is weird but ok', {static: true, direction: 'bottom'});
L.polyline([[41.20, 9.36], [41.205, 9.35], [41.19, 9.34]]).addTo(map).bindLabel('Polyline label', {static: true, direction: 'top'});
L.polygon([[41.21, 9.36], [41.24, 9.35], [41.23, 9.34]]).addTo(map).bindLabel('Top label following mouse', {followMouse: true, direction: 'top'});
L.marker([41.18, 9.35]).addTo(map).bindLabel('Top label is top', {permanent: true, direction: 'top'});
L.marker([41.173, 9.37]).addTo(map).bindLabel('Bottom label is weird but ok', {permanent: true, direction: 'bottom'});
L.polyline([[41.20, 9.36], [41.205, 9.35], [41.19, 9.34]]).addTo(map).bindLabel('Polyline label', {permanent: true, direction: 'top'});
L.polygon([[41.21, 9.36], [41.24, 9.35], [41.23, 9.34]]).addTo(map).bindLabel('Top label following mouse', {sticky: true, direction: 'top'});
</script>
</body>

12
dist/leaflet.css vendored
View File

@ -526,11 +526,9 @@
/* Label */
.leaflet-label {
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.8);
background: white;
background-clip: padding-box;
border-color: #777;
border-color: rgba(255,255,255,0.8);
border-color: white;
border-radius: 2px;
border-style: solid;
border-width: 4px;
@ -581,8 +579,7 @@
.leaflet-label-top:before {
/* Calc include 4 px of border - minus half of the 6px of tip size */
left: calc(-50% + 1px);
border-top-color: black;
border-top-color: rgba(255,255,255,0.8);
border-top-color: white;
position: relative;
top: 29px;
}
@ -614,8 +611,7 @@
.leaflet-label-bottom:before {
/* Calc include 4 px of border - minus half of the 6px of tip size */
left: calc(-50% + 1px);
border-bottom-color: black;
border-bottom-color: rgba(255,255,255,0.8);
border-bottom-color: white;
position: relative;
top: -28px;
}

View File

@ -36,17 +36,17 @@ describe('Label', function () {
expect(map.hasLayer(layer._label)).to.be(false);
});
it("stays open on marker when static", function () {
it("stays open on marker when permanent", function () {
var layer = new L.Marker(center).addTo(map);
layer.bindLabel('Label', {static: true});
layer.bindLabel('Label', {permanent: true});
expect(map.hasLayer(layer._label)).to.be(true);
});
it("is removed when removing marker", function () {
var layer = new L.Marker(center).addTo(map);
layer.bindLabel('Label', {static: true});
layer.bindLabel('Label', {permanent: true});
expect(map.hasLayer(layer._label)).to.be(true);
layer.remove();
expect(map.hasLayer(layer._label)).to.be(false);
@ -57,7 +57,7 @@ describe('Label', function () {
var spy = sinon.spy();
layer.on('click', spy);
layer.bindLabel('Label', {static: true, interactive: true});
layer.bindLabel('Label', {permanent: true, interactive: true});
happen.click(layer._label._container);
expect(spy.calledOnce).to.be(true);
});
@ -68,7 +68,7 @@ describe('Label', function () {
var spy = sinon.spy();
layer.on('click', spy);
layer.bindLabel('A long label that should be displayed on the left', {static: true, direction: 'left', interactive: true});
layer.bindLabel('A long label that should be displayed on the left', {permanent: true, direction: 'left', interactive: true});
expect(map.hasLayer(layer._label)).to.be(true);
happen.at('click', 150, 190); // Marker is on the map center, which is 400px large.
expect(spy.calledOnce).to.be(true);
@ -76,14 +76,14 @@ describe('Label', function () {
it("honours opacity option", function () {
var layer = new L.Marker(center).addTo(map);
layer.bindLabel('Label', {static: true, opacity: 0.57});
layer.bindLabel('Label', {permanent: true, opacity: 0.57});
expect(layer._label._container.style.opacity).to.eql(0.57);
});
it("can change opacity with setOpacity", function () {
var layer = new L.Marker(center).addTo(map);
layer.bindLabel('Label', {static: true});
expect(layer._label._container.style.opacity).to.eql(1);
layer.bindLabel('Label', {permanent: true});
expect(layer._label._container.style.opacity).to.eql(0.8);
layer._label.setOpacity(0.57);
expect(layer._label._container.style.opacity).to.eql(0.57);
});
@ -121,10 +121,10 @@ describe('Label', function () {
expect(map.hasLayer(layer._label)).to.be(false);
});
it("stays open on polygon when static", function () {
it("stays open on polygon when permanent", function () {
var layer = new L.Polygon([[55.8, 37.6], [55.9, 37.6], [55.8, 37.5]]).addTo(map);
layer.bindLabel('Label', {static: true});
layer.bindLabel('Label', {permanent: true});
expect(map.hasLayer(layer._label)).to.be(true);
});
@ -141,10 +141,10 @@ describe('Label', function () {
expect(map.hasLayer(layer._label)).to.be(false);
});
it("stays open on marker when static", function () {
it("stays open on marker when permanent", function () {
var layer = new L.Polyline([[55.8, 37.6], [55.9, 37.6], [55.8, 37.5]]).addTo(map);
layer.bindLabel('Label', {static: true});
layer.bindLabel('Label', {permanent: true});
expect(map.hasLayer(layer._label)).to.be(true);
});

View File

@ -108,6 +108,11 @@ GeoJSON ID of the feature (if present).
@property popup: Popup
The popup that was opened or closed.
@miniclass LabelEvent (Event objects)
@inherits Event
@property label: Label
The label that was opened or closed.
@miniclass DragEndEvent (Event objects)
@inherits Event
@property distance: Number

View File

@ -1,47 +1,100 @@
/*
* L.Label is used for displaying small texts on the map.
* @class Label
* @inherits PopupBase
* @aka L.Label
* Used to display small texts on top of map layers.
*
* @example
*
* ```js
* marker.bindLabel("my label text").openLabel();
* ```
* Note about label offset. Leaflet takes two options in consideration
* for computing label offseting:
* - the `offset` Label option: it defaults to [6, -6], because the label
* tip is 6px width and height. Remember to change this value if you override
* the tip in CSS.
* - the `labelAnchor` Icon option: this will only be considered for Marker. You
* should adapt this value if you use a custom icon.
*/
// @namespace Label
L.Label = L.PopupBase.extend({
// @section
// @aka Label options
options: {
// @option pane: String = 'labelPane'
// `Map pane` where the label will be added.
pane: 'labelPane',
// @option offset: Point = Point(6, -6)
// The offset of the label position. Update it if you customize the
// label tip in CSS.
offset: [6, -6],
// @option direction: String = 'right'
// Direction where to open the label. Possible values are: `right`, `left`,
// `top`, `bottom`, `auto`.
// `auto` will dynamicaly switch between `right` and `left` according to the label
// position on the map.
direction: 'right',
static: false, // Reserved word, use "permanent" instead?
followMouse: false,
// @option permanent: Boolean = false
// Whether to open the label permanently or only on mouseover.
permanent: false,
// @option sticky: Boolean = false
// If true, the label will follow the mouse instead of being fixed at the feature center.
sticky: false,
// @option interactive: Boolean = false
// If true, the label will listen to the feature events.
interactive: false,
opacity: 1,
// className: '',
zoomAnimation: true
// @option opacity: Number = 1.0
// Label container opacity.
opacity: 0.8
},
onAdd: function (map) {
L.PopupBase.prototype.onAdd.call(this, map);
this.setOpacity(this.options.opacity);
map.fire('labelopen', {popup: this});
// @namespace Map
// @section Label events
// @event labelopen: LabelEvent
// Fired when a label is opened in the map.
map.fire('labelopen', {label: this});
if (this._source) {
this._source.fire('labelopen', {popup: this}, true);
// @namespace Layer
// @section Label events
// @event labelopen: LabelEvent
// Fired when a label bound to this layer is opened.
this._source.fire('labelopen', {label: this}, true);
}
},
onRemove: function (map) {
L.PopupBase.prototype.onRemove.call(this, map);
map.fire('labelclose', {popup: this});
// @namespace Map
// @section Label events
// @event labelclose: LabelEvent
// Fired when a label in the map is closed.
map.fire('labelclose', {label: this});
if (this._source) {
this._source.fire('labelclose', {popup: this}, true);
// @namespace Layer
// @section Label events
// @event labelclose: LabelEvent
// Fired when a label bound to this layer is closed.
this._source.fire('labelclose', {label: this}, true);
}
},
openOn: function (map) {
map.openLabel(this);
return this;
},
_close: function () {
if (this._map) {
this._map.closeLabel(this);
@ -110,17 +163,27 @@ L.Label = L.PopupBase.extend({
_getAnchor: function () {
// Where should we anchor the label on the source layer?
return L.point(this._source._getLabelAnchor && !this.options.followMouse ? this._source._getLabelAnchor() : [0, 0]);
return L.point(this._source._getLabelAnchor && !this.options.sticky ? this._source._getLabelAnchor() : [0, 0]);
}
});
// @namespace Label
// @factory L.label(options?: Label options, source?: Layer)
// Instantiates a Label object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the label with a reference to the Layer to which it refers.
L.label = function (options, source) {
return new L.Label(options, source);
};
// @namespace Map
// @section Methods for Layers and Controls
L.Map.include({
// @method openLabel(label: Label): this
// Opens the specified label.
// @alternative
// @method openLabel(content: String|HTMLElement, latlng: LatLng, options?: Label options): this
// Creates a label with the specified content and options and open it.
openLabel: function (label, latlng, options) {
if (!(label instanceof L.Label)) {
label = new L.Label(options).setContent(label);
@ -137,10 +200,13 @@ L.Map.include({
return this.addLayer(label);
},
// @method closeLabel(label?: Label): this
// Closes the label given as parameter.
closeLabel: function (label) {
if (label) {
this.removeLayer(label);
}
return this;
}
});

View File

@ -1,9 +1,23 @@
/*
* Adds label-related methods to all layers.
* @namespace Layer
* @section Label methods example
*
* All layers share a set of methods convenient for binding labels to it.
*
* ```js
* var layer = L.Polygon(latlngs).bindLabel('Hi There!').addTo(map);
* layer.openLabel();
* layer.closeLabel();
* ```
*/
// @section Label methods
L.Layer.include({
// @method bindLabel(content: String|HTMLElement|Function|Label, options?: Label options): this
// Binds a label to the layer with the passed `content` and sets up the
// neccessary event listeners. If a `Function` is passed it will receive
// the layer as the first argument and should return a `String` or `HTMLElement`.
bindLabel: function (content, options) {
if (content instanceof L.Label) {
@ -22,11 +36,13 @@ L.Layer.include({
this._initLabelInteractions();
if (this._label.options.static) { this.openLabel(); }
if (this._label.options.permanent) { this.openLabel(); }
return this;
},
// @method unbindLabel(): this
// Removes the label previously bound with `bindLabel`.
unbindLabel: function () {
if (this._label) {
this._initLabelInteractions(true);
@ -42,10 +58,10 @@ L.Layer.include({
remove: this.closeLabel,
move: this._moveLabel
};
if (!this._label.options.static) {
if (!this._label.options.permanent) {
events.mouseover = this._openLabel;
events.mouseout = this.closeLabel;
if (this._label.options.followMouse) {
if (this._label.options.sticky) {
events.mousemove = this._moveLabel;
}
if (L.Browser.touch) {
@ -56,6 +72,8 @@ L.Layer.include({
this._labelHandlersAdded = !remove;
},
// @method openLabel(latlng?: LatLng): this
// Opens the bound label at the specificed `latlng` or at the default label anchor if no `latlng` is passed.
openLabel: function (layer, latlng) {
if (!(layer instanceof L.Layer)) {
latlng = layer;
@ -93,6 +111,8 @@ L.Layer.include({
return this;
},
// @method closeLabel(): this
// Closes the label bound to this layer if it is open.
closeLabel: function () {
if (this._label) {
this._label._close();
@ -104,6 +124,8 @@ L.Layer.include({
return this;
},
// @method toggleLabel(): this
// Opens or closes the label bound to this layer depending on its current state.
toggleLabel: function (target) {
if (this._label) {
if (this._label._map) {
@ -115,10 +137,14 @@ L.Layer.include({
return this;
},
// @method isLabelOpen(): boolean
// Returns `true` if the label bound to this layer is currently open.
isLabelOpen: function () {
return this._label.isOpen();
},
// @method setLabelContent(content: String|HTMLElement|Label): this
// Sets the content of the label bound to this layer.
setLabelContent: function (content) {
if (this._label) {
this._label.setContent(content);
@ -126,6 +152,8 @@ L.Layer.include({
return this;
},
// @method getLabel(): Label
// Returns the label bound to this layer.
getLabel: function () {
return this._label;
},
@ -136,12 +164,12 @@ L.Layer.include({
if (!this._label || !this._map) {
return;
}
this.openLabel(layer, this._label.options.followMouse ? e.latlng : undefined);
this.openLabel(layer, this._label.options.sticky ? e.latlng : undefined);
},
_moveLabel: function (e) {
var latlng = e.latlng, containerPoint, layerPoint;
if (this._label.options.followMouse && e.originalEvent) {
if (this._label.options.sticky && e.originalEvent) {
containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent);
layerPoint = this._map.containerPointToLayerPoint(containerPoint);
latlng = this._map.layerPointToLatLng(layerPoint);

View File

@ -108,7 +108,7 @@ L.Layer.include({
return this;
},
// @method closePopup(): this
// @method togglePopup(): this
// Opens or closes the popup bound to this layer depending on its current state.
togglePopup: function (target) {
if (this._popup) {
@ -121,13 +121,13 @@ L.Layer.include({
return this;
},
// @method closePopup(): this
// @method isPopupOpen(): boolean
// Returns `true` if the popup bound to this layer is currently open.
isPopupOpen: function () {
return this._popup.isOpen();
},
// @method setPopupContent(content: String|HTMLElement|Popup, options?: Popup options): this
// @method setPopupContent(content: String|HTMLElement|Popup): this
// Sets the content of the popup bound to this layer.
setPopupContent: function (content) {
if (this._popup) {

View File

@ -69,7 +69,6 @@ L.Popup = L.PopupBase.extend({
// @section Popup events
// @event popupclose: PopupEvent
// Fired when a popup bound to this layer is closed
// @namespace Popup
this._source.fire('popupclose', {popup: this}, true);
this._source.off('preclick', L.DomEvent.stopPropagation);
}