modestmaps / modestmaps-js

Modest Maps javascript port
http://modestmaps.com
395 stars 73 forks source link

Scrollzoom off on maps with fixed position #60

Open yhahn opened 11 years ago

yhahn commented 11 years ago

Test case:

http://bl.ocks.org/4601671

From MapBox Support 954

When loading the JS API into a "position: fixed" modal, if you scroll the page past the fold and then zoom in and out via mousewheel, the zoom center point is off zia the same distance the page has scrolled.

Using the code from the mouse position tutorial ( http://mapbox.com/mapbox.js/example/mouse-position/ ), when at the top of the document, the mouse y is 0 when at the top of the map container. The more you scroll down the page, position the cursor at the top of map container, it no longer reads 0, but an offset of how far the page has scrolled.

I've tried CSS position "static", "relative", "absolute" and widths and heights on the map container and it's parents, upto the modal container.

If looks like the zoom point is calculated via the mouse position on the document, not via the window. Is this a know issue or is there a fix?

MateoV commented 11 years ago

The culprit is these two lines in MM.getMousePoint https://github.com/modestmaps/modestmaps-js/blob/master/modestmaps.js#L866-867.

Simply wrapping these in an if statement based on whether or not the map div has position: fixed works, but this is dependent on the user placing the fixed attribute on the map div and not some higher level container. Also not positive if this covers all possible uses of fixed.

Sticking a custom version of the function in your site works well, for example:

  MM.getMousePoint = function(e, map) {
      // start with just the mouse (x, y)
      var point = new MM.Point(e.clientX, e.clientY);

      if (!$('.map-container').hasClass('fixed')) {
          // correct for scrolled document
          point.x += document.body.scrollLeft + document.documentElement.scrollLeft;
          point.y += document.body.scrollTop + document.documentElement.scrollTop;
      }

      // correct for nested offsets in DOM
      for (var node = map.parent; node; node = node.offsetParent) {
          point.x -= node.offsetLeft;
          point.y -= node.offsetTop;
      }
      return point;
  };