How do I stop the map jiggling up and down?

425 views
Skip to first unread message

Paul Whipp

unread,
Oct 10, 2013, 8:20:26 PM10/10/13
to leafl...@googlegroups.com
I've got the map looking and behaving how I want it with this:

    lmap = L.map('map', {minZoom: 2,
maxZoom: 16})
    lmap.fitWorld()
    lmap.setMaxBounds(lmap.getBounds()) // Keep it here if zoomed out and panned about

It works fine and the map is stable when zoomed in but at the starting level of zoom (2) the map jiggles up and down constantly by a pixel or two which is currently just annoying but is presumably soaking up processing in some sort of loop so could cause me a lot of grief in future.

How do I stop it jiggling?

Cheers,
Paul

Paul Whipp

unread,
Oct 11, 2013, 4:21:29 AM10/11/13
to leafl...@googlegroups.com
I've got the problem running on a (micro so very slow) test server here: http://www.footholdgame.com/experiments/scratch_test/

Michael Moore

unread,
Oct 11, 2013, 8:08:21 AM10/11/13
to leafl...@googlegroups.com
The map jiggles for me, but then my browser freezes up after a few minutes of having your map loaded (Firefox 23 / Windows 7 x64).

When I load the page with Firebug enabled I get a message "too much recursion" and a line number in the middle of the compressed leaflet.js file.

Can you change

<script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"></script>

to

<script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet-src.js"></script>

so that the debug messages are more useful?

Then you could use the Firebug "Break on Next" button to get into the recursion and see what's going on: https://getfirebug.com/wiki/index.php/Script_Panel#Break_On_Next

I suspect that if you end the recursion you'll end the jiggling.

--
Michael Moore

Paul Whipp

unread,
Oct 12, 2013, 3:46:17 AM10/12/13
to leafl...@googlegroups.com
Will do, thanks for the tip. The recursion appears to be entirely within leaflet but with the source i'll see if I can find out what is happening.


--
 
---
You received this message because you are subscribed to a topic in the Google Groups "Leaflet" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/leaflet-js/G4v3bJUufz4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to leaflet-js+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Paul Whipp

unread,
Oct 14, 2013, 7:12:45 PM10/14/13
to leafl...@googlegroups.com

OK. This is my first attempt at debugging leaflet code… A quick search through the source shows that it's using the panInsideBounds function to constrain the map to the max bounds. This function is being called repeatedly leading to the jitter.

In the function we see it calling panBy which is tripping a move event which is tripping the panInsideBounds again causing the infinite loop.

Looking at the variables in chrome's console:

viewNe
L.Point {x: 1024, y: 132, clone: function, add: function, _add: function…}
ne
L.Point {x: 1024, y: 132.00000000000006, clone: function, add: function, _add: function…}
viewSw
L.Point {x: 0, y: 892, clone: function, add: function, _add: function…}
sw
L.Point {x: 0, y: 892.0000000000001, clone: function, add: function, _add: function…}

The use of the Math.ceil function is causing a repeated 1px jump in dy.

I'm not sure what the solution to this should be - perhaps we are projecting to pixels, so the project function itself should perhaps handle the rounding. Alternatively we should not be doing the ceiling and floor mapping in the panInsideBounds function.

In either case, rounding the projected values in panInsideBounds fixes the problem as a workaround:

panInsideBounds: function (bounds) {
	bounds = L.latLngBounds(bounds);

	var viewBounds = this.getPixelBounds(),
	    viewSw = viewBounds.getBottomLeft(),
	    viewNe = viewBounds.getTopRight(),
	    sw = this.project(bounds.getSouthWest()),
	    ne = this.project(bounds.getNorthEast()),
	    swx = Math.Round(sw.x),
	    swy = Math.Round(sw.y),
	    nex = Math.Round(ne.x),
	    ney = Math.Round(ne.y),
	    dx = 0,
	    dy = 0;

	if (viewNe.y < ney) { // north
		dy = Math.ceil(ney - viewNe.y);
	}
	if (viewNe.x > nex) { // east
		dx = Math.floor(nex - viewNe.x);
	}
	if (viewSw.y > swy) { // south
		dy = Math.floor(swy - viewSw.y);
	}
	if (viewSw.x < swx) { // west
		dx = Math.ceil(swx - viewSw.x);
	}

	if (dx || dy) {
		return this.panBy([dx, dy]);
	}

	return this;

Thanks for pointing me in the right direction. I've updated what appears to be a related leaflet issue

Michael Moore

unread,
Oct 14, 2013, 7:50:04 PM10/14/13
to leafl...@googlegroups.com
I have a hazy memory that I might have seen this.

Is there a chance that your browser zoom isn't at 100% on that web page? If you're on Firefox or Chrome you can reset your zoom to 100% by doing ctrl-0 (zero).

I think this might have happened to me once before and changing my web page zoom level fixed it.
--
Michael


--
 
---
You received this message because you are subscribed to the Google Groups "Leaflet" group.
To unsubscribe from this group and stop receiving emails from it, send an email to leaflet-js+...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
Support the digitization of the Iron County Miner newspaper archives
Like this project on Facebook: https://www.facebook.com/digitizeicm

Paul Whipp

unread,
Oct 14, 2013, 7:53:53 PM10/14/13
to leafl...@googlegroups.com
No. You can test that theory on http://www.footholdgame.com/experiments/scratch_test/ - it is the rounding issue I describe above that is causing the recursion.


--
 
---
You received this message because you are subscribed to a topic in the Google Groups "Leaflet" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/leaflet-js/G4v3bJUufz4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to leaflet-js+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages