diff --git a/js/id/modes/select.js b/js/id/modes/select.js index 84f58a4d8..8888e9bc8 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -92,6 +92,10 @@ iD.modes.Select = function(entity, initial) { surface.call(radialMenu.close); }); + map.on('move.select', function() { + surface.call(radialMenu.close); + }); + function click() { var datum = d3.select(d3.event.target).datum(); if (datum instanceof iD.Entity) { diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index fd3c2420a..f34ee03cc 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -126,6 +126,7 @@ iD.Map = function() { return d3.event.sourceEvent.preventDefault(); } } + if (Math.log(d3.event.scale / Math.LN2 - 8) < minzoom + 1) { iD.flash() .select('.content') @@ -151,6 +152,8 @@ iD.Map = function() { tilegroup.style(transformProp, transform); surface.style(transformProp, transform); queueRedraw(); + + dispatch.move(map); } function resetTransform() { @@ -161,7 +164,6 @@ iD.Map = function() { function redraw(difference) { resetTransform(); - dispatch.move(map); surface.attr('data-zoom', ~~map.zoom()); tilegroup.call(background); if (map.editable()) { @@ -212,6 +214,8 @@ iD.Map = function() { }; function setZoom(z) { + if (z === map.zoom()) + return false; var scale = 256 * Math.pow(2, z), center = pxCenter(), l = pointLocation(center); @@ -224,16 +228,20 @@ iD.Map = function() { t[1] += center[1] - l[1]; projection.translate(t); zoom.translate(projection.translate()); + return true; } function setCenter(loc) { var t = projection.translate(), c = pxCenter(), ll = projection(loc); + if (ll[0] === c[0] && ll[1] === c[1]) + return false; projection.translate([ t[0] - ll[0] + c[0], t[1] - ll[1] + c[1]]); zoom.translate(projection.translate()); + return true; } map.size = function(_) { @@ -250,23 +258,35 @@ iD.Map = function() { map.center = function(loc) { if (!arguments.length) { return projection.invert(pxCenter()); - } else { - setCenter(loc); - return redraw(); } + + if (setCenter(loc)) { + dispatch.move(map); + } + + return redraw(); }; map.zoom = function(z) { if (!arguments.length) { return Math.max(Math.log(projection.scale()) / Math.LN2 - 8, 0); } - setZoom(z); + + if (setZoom(z)) { + dispatch.move(map); + } + return redraw(); }; map.centerZoom = function(loc, z) { - setCenter(loc); - setZoom(z); + var centered = setCenter(loc), + zoomed = setZoom(z); + + if (centered || zoomed) { + dispatch.move(map); + } + return redraw(); }; diff --git a/test/spec/renderer/map.js b/test/spec/renderer/map.js index 5070bdffa..d7d0e3440 100644 --- a/test/spec/renderer/map.js +++ b/test/spec/renderer/map.js @@ -24,6 +24,22 @@ describe('iD.Map', function() { expect(map.zoom(4)).to.equal(map); expect(map.zoom()).to.equal(4); }); + + it('dispatches move event when zoom changes', function() { + var spy = sinon.spy(); + map.zoom(4); + map.on('move', spy); + map.zoom(5); + expect(spy).to.have.been.called; + }); + + it('dispatches no move event when zoom does not change', function() { + var spy = sinon.spy(); + map.zoom(4); + map.on('move', spy); + map.zoom(4); + expect(spy).not.to.have.been.called; + }); }); describe('#zoomIn', function() { @@ -56,6 +72,22 @@ describe('iD.Map', function() { expect(map.center()[0]).to.be.closeTo(10, 0.5); expect(map.center()[1]).to.be.closeTo(15, 0.5); }); + + it('dispatches move event when center changes', function() { + var spy = sinon.spy(); + map.center([0, 0]); + map.on('move', spy); + map.center([1, 1]); + expect(spy).to.have.been.called; + }); + + it('dispatches no move event when center does not change', function() { + var spy = sinon.spy(); + map.center([0, 0]); + map.on('move', spy); + map.center([0, 0]); + expect(spy).not.to.have.been.called; + }); }); describe('#centerEase', function() {