Reputation: 6362
I have a leaflet map with a LineString
.
// a GeoJSON LineString
var geojson = {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-101.123, 40.2500], [-101.123, 40.2503]]
}
};
// create map and add json
var map = L.map('map');
var geojsonLayer = new L.GeoJSON(geojson).addTo(map);
map.fitBounds(geojsonLayer.getBounds())
// add popup for the line
geojsonLayer.eachLayer(function (layer) {
var popup = L.popup();
popup.setContent('text');
layer.bindPopup(popup);
layer.on('click mouseover', function () {
layer.openPopup();
});
});
When I over it, a popup opens at the LineString center.
How can I make it open over at the cursor position?
Here is a simple working example: http://jsfiddle.net/wuu8Lv2t/1/
Upvotes: 2
Views: 6777
Reputation: 185
The accepted answer (by @YaFred) is pretty good, what's key is the update function layer.on('mousemove'...
. However, as written, closing and opening the popup every time your mouse moves, makes it flicker. Instead, in layer.('mousemove...
you only need the line that updates the location:
// add popup for the layer
geojsonLayer.eachLayer(function (layer) {
var popup = L.popup();
popup.setContent('text');
layer.bindPopup(popup);
layer.on('mouseover', function (e) {
var popup = e.target.getPopup();
popup.setLatLng(e.latlng).openOn(map);
});
layer.on('mouseout', function(e) {
e.target.closePopup();
});
// update popup location
layer.on('mousemove', function (e) {
popup.setLatLng(e.latlng).openOn(map);
});
});
Upvotes: 2
Reputation: 6362
Here is a an answer from Per Liedman, a Leaflet maintainer:
You can achieve this by creating a new popup and adding at the desired location, instead of binding it. Since a bound popup can be opened by other means than a mouse click, it can't know where to open.
Here is the corresponding code:
// a GeoJSON LineString
var geojson = {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-101.123, 40.2500], [-101.123, 40.2503]]
}
};
// create map and add json
var map = L.map('map');
var geojsonLayer = new L.GeoJSON(geojson).addTo(map);
map.fitBounds(geojsonLayer.getBounds())
// add popup for the line
geojsonLayer.eachLayer(function (layer) {
layer.on('click mouseover', function (e) {
var popup = L.popup()
.setLatLng(e.latlng)
.setContent('text')
.openOn(map);
});
});
See here for a modified example: http://jsfiddle.net/uwdnvfy6/
Upvotes: 2
Reputation: 10008
Don't let the layer open the popup, instead use openOn(map)
setting the position with the coordinates from the event e.latlng
// add popup for the line
geojsonLayer.eachLayer(function (layer) {
var popup = L.popup();
popup.setContent('text');
layer.bindPopup(popup);
layer.on('mouseover', function (e) {
var popup = e.target.getPopup();
popup.setLatLng(e.latlng).openOn(map);
});
layer.on('mouseout', function(e) {
e.target.closePopup();
});
layer.on('mousemove', function (e) {
e.target.closePopup();
var popup = e.target.getPopup();
popup.setLatLng(e.latlng).openOn(map);
});
});
Note that in your question there is a mistake: you can't use the variable layer
in the event hander, you have to use e.target
(see doc).
Upvotes: 5