Leaflet: Marker drifts on zoom / marker jumps around on zoom

Created on 11 Jan 2018  路  21Comments  路  Source: Leaflet/Leaflet

Issue 1. Marker drifts on zoom (does not stay centered on the map, when marker and map is on same coordinates)
Reproduce: go to https://jsfiddle.net/o0yfm5zy/1/
Click button first, and then zoom.

Issue 2. marker jumps around on zoom (only about a pixel or so but it is noticeable, especially when you use flyTo() on retina screen).
Reproduce: on the jsfiddle, click the button again (or re-run) and zoom

I experience the same behaviour on firefox, chromium/opera and ios.

Most helpful comment

Hi @camaulay,

In your reproduction example, the culprit is your custom CSS rule position: relative on Marker Icon class:

var markerIcon = L.divIcon({
  className: 'marker-icon',
  iconSize: [16,16],
  iconAnchor: [8,8],
});
.marker-icon {
  background-color: red;
  border-radius: 16px;
  position: relative; /* Affects Leaflet behaviour */
}

Disabling this custom rule restores Leaflet expected behaviour: https://jsfiddle.net/apmwzcfj/

All 21 comments

Bump!

Any workaround to make the marker and map always on the same exact location?
And to keep the marker at the same exact place through zoom-levels?

Hi. I can confirm the issue. This 'drift' seems to be caused by pixel coordinates repeatedly being used to calculate the centre of the map after an initial pan or pan-and-zoom operation. I think I can see a simple fix in the setView function, but I need to confirm with some further testing. This should also take care of the 'wobble' you're seeing on zoom, too.

Interestingly, there's already a test called zoom-remain-centered.html in the source, but it doesn't cover the pre-panning case, so this must be why it hasn't previously been detected.

@daverayment thanks for looking into this, looking forward to a solution.

Hi,

Probably related to https://github.com/Leaflet/Leaflet/issues/3737 (issue description sounds like dupe https://github.com/Leaflet/Leaflet/issues/5512)

Hmm, I don't think this is the same as #3737, which is about zooming based on the mouse location, not the 'drifting' of the centre. They both probably have a common cause in the (necessary) rounding to pixel coords, however.

My initial simple fix didn't work, but I have another attempt which looks more promising. Unfortunately, it's a fair bit more involved, so I'll write it up for further discussion once I've done some more testing. Sorry about the delay, @feature7

@feature7 could you try the following please?

https://jsfiddle.net/o0yfm5zy/20/

I've had to copy in all the Leaflet code, so it will be a little slow! Hopefully, you'll still be able to check whether it tackles the drifting issue for you, though. Let me now how it goes.

Great!
From what I can see, the drifting issue is solved, chromium, firefox, ios, marker remains centred. Tried some random locations as well. Hope to see it in next release.

Did some more checking with the new code, @daverayment your fix is solid.

But I noticed one case where there still is 'drift' of marker on zoom. If I scroll with the finger on the page first on ios browsers (page viewport" set to: "width=device-width, initial-scale=1.0"), the initial marker will drift, if I don't scroll first it will not. I've repeated the test to confirm I didn't accidentally tap the map, but I always get the same drift after scroll.
This I can only reproduce on ios, and webkit browsers (not in app-mode, where everything works fine).
To reproduce just set a margin-bottom on element above map until scrollbar is shown.
On ios safari scroll and then zoom with the control.

I am seeing this as well, but I'd like to add by using the zoom buttons (+ and -). Mind you, my custom icon has proper (verified) iconSize, with iconAnchor: [16, 2], and popupAnchor: [0, -3]. I'm also finding it with a custom icon. The same implementation without custom icons renders fine.

Smells like the custom icon positioning system.

I discovered that on the y-axis the offset between iconSize and iconAnchor sums up with each marker added to the map. So the 10th marker is 8 pixels below the desired point. This is independent of the zoom level. A polyline along the coordinates proof that this is an issue of the marker, NOT of coordinates. Resume: Most likely the evaluation of the absolute iconAnchor has a bug as a helper variable is not reset before calculating the position of the next marker.

Example code for a custom marker with iconAnchor:

aIconNumbered[iPoint] = L.divIcon({
className: CIconColorClass,
iconSize: [32, 68],
iconAnchor: [2, 66],
tooltipAnchor: [0, 0], // No effect
popupAnchor: [0, 0], // No effect
html: String.fromCharCode(bAscBaseCode + iPoint)
});
for (iPoint = 0; iPoint < bMaxNumOfPoints; iPoint++)
{
aPin[iPoint] = L.marker(latlngs[iPoint], {icon: aIconNumbered[iPoint]}).bindTooltip(aTourData[iPoint][3],
{opacity: 0.8 }).openTooltip(); // Tooltip am Pin
aPin[iPoint].addTo(mymap); // Pin auf der Radlstrecke
}

Checked with Firefox 65.0.1 and Leaflet 1.4.0+Detached

The bug described by @FReiradler still exists in Leaflet 1.5.1

See fiddle here: https://jsfiddle.net/c302ueh8/2/

Note: switching map markers from instances of divIcon to the default icon option make the markers place perfectly at all zoom levels, this only occurs with custom icons.

The following fiddle places two markers (custom and default) and the same coordinates, notice how much the custom markers drift.

https://jsfiddle.net/x9524oaz/

Hi @camaulay,

In your reproduction example, the culprit is your custom CSS rule position: relative on Marker Icon class:

var markerIcon = L.divIcon({
  className: 'marker-icon',
  iconSize: [16,16],
  iconAnchor: [8,8],
});
.marker-icon {
  background-color: red;
  border-radius: 16px;
  position: relative; /* Affects Leaflet behaviour */
}

Disabling this custom rule restores Leaflet expected behaviour: https://jsfiddle.net/apmwzcfj/

@ghybs, that's a good find. However I'm not using any position attribute and I'm still getting the drift.

var homeIcon = L.icon({
    iconUrl: '/img/home_location.png',
    iconSize:     [32, 37],
    iconAnchor:   [16, 2],
    popupAnchor:  [0, -3]
    });

L.marker([ 43.664799, -79.341603 ], {icon: homeIcon}).bindPopup("Home").addTo(targets);

Hi @daBee,

Please can you share a reproduction example?

@ghybs Just posted here, but I can't get my custom icon into the included files with this site (I'm new to this): https://jsfiddle.net/daBee/be06usd5/3/

Any advice how I can do that?

@daBee you can simply have your image hosted, or use other similar code sharing tools like Plunker or StackBlitz. Another solution is to simply inline a base64 encoded image, possibly much simplified.

@ghybs Sorry...was tired. It's fixed now. https://jsfiddle.net/daBee/be06usd5/5/

Hi @daBee,

Thank you for the reproduction example!

If I understand correctly, you try using the below image as Marker custom Icon:
home_location
with custom icon options specified as:

iconSize:     [32, 37],
iconAnchor:   [16, 2],

Because its "tip" is at the bottom of the image, you would rather expect the "y" value of iconAnchor option to be about the height of the image, i.e. 37 pixels, instead of 2 as above specified.

A useful "trick" to check your custom icon options, is to place another Marker with default icon at the _exact same coordinates_. See also this post on SO: Explanation of Leaflet Custom Icon LatLng vs XY Coordinates

Once the anchor coordinates (same for popup) are corrected, your custom icon no longer drifts: https://jsfiddle.net/4ur7eyc9/

Therefore your issue seems totally unrelated to OP.

@ghybs Excellent. This was some time ago, so I forget how I was trying to line up the wee pointer at the bottom.

Hello,

We still face this problem in the latest version of Leaflet! Is there an official fix or a solution compatible with the latest release?

@nash-ye I got mine fixed. Have you measured iconSize and iconAnchor?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pgeyman picture pgeyman  路  3Comments

brambow picture brambow  路  3Comments

CallMarl picture CallMarl  路  3Comments

prbaron picture prbaron  路  3Comments

broofa picture broofa  路  4Comments