kartena / Proj4Leaflet

Smooth Proj4js integration with Leaflet.
http://kartena.github.io/Proj4Leaflet/
BSD 2-Clause "Simplified" License
589 stars 173 forks source link

Strange moving markers and non moving ImageLayers during pinch zoom action #57

Closed tebben closed 9 years ago

tebben commented 10 years ago

In my Leaflet project I'm using Proj4Leaflet with EPSG:28992 (RD_NEW) http://spatialreference.org/ref/epsg/28992/ which works pretty nice but I found some issues with markers and ImageLayers when zooming in and out using pinch zoom.

While pinch zooming on the map you can see the markers moving but don't stick to their exact place but animate back to their right position again after the zoom action is finished. ImageLayers also have this behaviour but instead of moving while pinch zooming they stay at the exact spot but animate to the right location again when you are finished zooming. The problem does not occur when using the scrollwheel.

If I use Leaflet 0.7.1 build in CRS for instance: 4326 it all works fine but in case of 28992 I get this behaviour. Any idea?

JSFiddle: http://jsfiddle.net/3TTqd/4/

perliedman commented 10 years ago

I'm not exactly sure what is going on here, but noticed that the zoom animation uses the method Map.getZoomScale, which has the following comment in 0.7.1: TODO replace with universal implementation after refactoring projections

I can't see exactly what the problem is, but from the looks of the method below, getScaleZoom, it looks like it's hardcoded against spherical Mercator's scales.

@mourner do you have any ideas? Should this be reported on Leaflet instead, or do you think it's already fixed in master, with the gridlayer and projection refactoring?

pkaariai commented 9 years ago

Problem is in L.Proj.CRS scale function which supports only integers. This seems to fix it:

this.scale = function (zoom) {
                var remainder = zoom % 1;
                if (remainder === 0) {
                    return this._scales[zoom];
                } else {
                    // pinch zoom may require scales for non-integer zoom levels
                    var lower = Math.floor(zoom),
                        upper = Math.ceil(zoom);
                    var lowerScale = this._scales[lower],
                        upperScale = this._scales[upper];
                    return lowerScale + (upperScale - lowerScale) * remainder;
                }
            }
perliedman commented 9 years ago

See #73.