Able to stack multiple layers, but mousepointer seems to only work with the top layer
Opened this issue · 7 comments
Mouse and click events fire regardless of layer, but the mouse does not change to "pointer" for markers that aren't in the top most L.MarkersCanvas().
const layers = {
bottom: new L.MarkersCanvas(),
middle: new L.MarkersCanvas(),
top: new L.MarkersCanvas(),
}
Only "top" layer has mouse pointer on hover.
Hello Michael,
The canvas on top prevents clicking on anything below. I don't know how to do something about this issue. Why don't you put all your markers in the same canvas instead?
I can move to a single layer by drawing the markers I want on top at the end of the loop, however, when I pan around the map the redraw doesnt seem to preserve the original order in which I drew the markers. Certain markers NEED to be on top in my application as they are more important than others.
Creating different layers allowed me to guarantee the important markers stay on top. But it removed my ability to have mouse over pointer. I'm open to ideas on how to move forward.
I was looking at the code and I think this issue can be resolved by making the following change:
Original Code:
} else {
this._map._container.style.cursor = "";
if (event.type === "mousemove" && this._mouseOverMarker) {
if (this._mouseOverMarker.listens("mouseout")) {
this._mouseOverMarker.fire("mouseout");
}
delete this._mouseOverMarker;
}
}
Proposed change:
} else {
if (event.type === "mousemove" && this._mouseOverMarker) {
// Relocated to inside the event.type.
// Basically only change the cursor to default, if we are leaving a marker
// --------------------------------------------------------
this._map._container.style.cursor = "";
// --------------------------------------------------------
if (this._mouseOverMarker.listens("mouseout")) {
this._mouseOverMarker.fire("mouseout");
}
delete this._mouseOverMarker;
}
}
Manually making this change in a local branch allows me to have multiple layers with multiple mouse over events and correctly functioning pointers.
Would you like me to make a PR for the change?
I gave a try with example below. The pointer changes on mouseover on both layers A and B.
Please make a repro to show your problem.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>leaflet-markers-canvas example</title>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<script src="https://unpkg.com/rbush@3.0.1/rbush.js"></script>
<script src="https://unpkg.com/leaflet-markers-canvas@0.2.2/dist/leaflet-markers-canvas.min.js"></script>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}
.container {
margin: 0 auto;
max-width: 1200px;
}
.map {
width: 100%;
height: 600px;
}
.header {
padding-top: 50px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>leaflet-markers-canvas</h1>
<p>
A Leaflet plugin to render many markers in a canvas instead of the
DOM.
</p>
<p>
<a href="https://github.com/francoisromain/leaflet-markers-canvas"
>https://github.com/francoisromain/leaflet-markers-canvas</a
>
</p>
</div>
<div class="map" id="map"></div>
</div>
<script>
var map = L.map("map").setView([59.9578, 30.2987], 10);
var tiles = L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution:
'© <a href="http://osm.org/copyright">OpenStreetMap</a>',
preferCanvas: true,
}).addTo(map);
var markersCanvasA = new L.MarkersCanvas();
map.addLayer(markersCanvasA);
var icon = L.icon({
iconUrl: "marker.png",
iconSize: [20, 32],
iconAnchor: [10, 0],
});
var markersA = [];
for (var i = 0; i < 100; i++) {
var marker = L.marker(
[58.5578 + Math.random() * 1.8, 29.0087 + Math.random() * 3.6],
{ icon }
)
.bindPopup("A" + i)
.on({
mouseover(e) {
this.openPopup();
},
mouseout(e) {
this.closePopup();
},
});
markersA.push(marker);
}
markersCanvasA.addMarkers(markersA);
var markersCanvasB = new L.MarkersCanvas();
map.addLayer(markersCanvasB);
var icon = L.icon({
iconUrl: "marker.png",
iconSize: [20, 32],
iconAnchor: [10, 0],
});
var markersB = [];
for (var i = 0; i < 100; i++) {
var marker = L.marker(
[58.5578 + Math.random() * 1.8, 29.0087 + Math.random() * 3.6],
{ icon }
)
.bindPopup("B" + i)
.on({
mouseover(e) {
this.openPopup();
},
mouseout(e) {
this.closePopup();
},
});
markersB.push(marker);
}
markersCanvasB.addMarkers(markersB);
</script>
</body>
</html>
I had the same issue, some markers on a "markers-canvas" and others on a native leaflet canvas, the "markers-canvas" was blocking pointer events from making it though to the native leaflet canvas. This css solves it:
canvas.leaflet-markers-canvas-layer {
pointer-events: none;
}
Should also add thanks for the plugin!!
I'm having the same problem I can't click on bottom layers
you can do this:
ciLayer._container.style.pointerEvents = 'none';
but you will loose al the pointer events in the top canvas