diff --git a/spec/suites/map/handler/Map.DragSpec.js b/spec/suites/map/handler/Map.DragSpec.js index afa5bad0..6c203298 100644 --- a/spec/suites/map/handler/Map.DragSpec.js +++ b/spec/suites/map/handler/Map.DragSpec.js @@ -22,7 +22,7 @@ describe("Map.Drag", function () { expect(map.dragging.enabled()).to.be(true); }); it("calls the map with dragging disabled and worldCopyJump enabled; " + - "enables dragging after setting center and zoom", function () { + "enables dragging after setting center and zoom", function () { var container = document.createElement('div'); var map = new L.Map(container, { dragging: false, @@ -43,7 +43,7 @@ describe("Map.Drag", function () { container.style.width = container.style.height = '600px'; container.style.top = container.style.left = 0; container.style.position = 'absolute'; -// container.style.background = '#808080'; + // container.style.background = '#808080'; document.body.appendChild(container); @@ -73,6 +73,46 @@ describe("Map.Drag", function () { mouse.wait(100).moveTo(200, 200, 0) .down().moveBy(5, 0, 20).moveBy(256, 32, 200).up(); }); + + it("does not change the center of the map when mouse is moved less than the drag threshold", function (done) { + var container = document.createElement('div'); + container.style.width = container.style.height = '600px'; + container.style.top = container.style.left = 0; + container.style.position = 'absolute'; + + document.body.appendChild(container); + + var map = new L.Map(container, { + dragging: true, + inertia: false + }); + + var originalCenter = L.latLng(0, 0); + map.setView(originalCenter, 1); + + var spy = sinon.spy(); + map.on('drag', spy); + + var hand = new Hand({ + timing: 'fastframe', + onStop: function () { + var center = map.getCenter(); + var zoom = map.getZoom(); + document.body.removeChild(container); + expect(center).to.be(originalCenter); // Expect center point to be the same as before the click + expect(spy.callCount).to.eql(0); // No drag event should have been fired. + expect(zoom).to.be(1); + + done(); + } + }); + var mouse = hand.growFinger('mouse'); + + // We move 2 pixels to stay below the default 3-pixel threshold of + // L.Draggable. This should result in a click and not a drag. + mouse.wait(100).moveTo(200, 200, 0) + .down().moveBy(1, 0, 20).moveBy(1, 0, 200).up(); + }); }); describe("touch events", function () { @@ -81,7 +121,7 @@ describe("Map.Drag", function () { container.style.width = container.style.height = '600px'; container.style.top = container.style.left = 0; container.style.position = 'absolute'; -// container.style.background = '#808080'; + // container.style.background = '#808080'; document.body.appendChild(container); @@ -111,6 +151,47 @@ describe("Map.Drag", function () { toucher.wait(100).moveTo(200, 200, 0) .down().moveBy(5, 0, 20).moveBy(256, 32, 200).up(); }); + + it("does not change the center of the map when finger is moved less than the drag threshold", function (done) { + var container = document.createElement('div'); + container.style.width = container.style.height = '600px'; + container.style.top = container.style.left = 0; + container.style.position = 'absolute'; + + document.body.appendChild(container); + + var map = new L.Map(container, { + dragging: true, + inertia: false + }); + + var originalCenter = L.latLng(0, 0); + map.setView(originalCenter, 1); + + var spy = sinon.spy(); + map.on('drag', spy); + + var hand = new Hand({ + timing: 'fastframe', + onStop: function () { + var center = map.getCenter(); + var zoom = map.getZoom(); + document.body.removeChild(container); + expect(center).to.be(originalCenter); // Expect center point to be the same as before the click + expect(spy.callCount).to.eql(0); // No drag event should have been fired. + expect(zoom).to.be(1); + + done(); + } + }); + + var toucher = hand.growFinger('touch'); + + // We move 2 pixels to stay below the default 3-pixel threshold of + // L.Draggable. This should result in a click and not a drag. + toucher.wait(100).moveTo(200, 200, 0) + .down().moveBy(1, 0, 20).moveBy(1, 0, 200).up(); + }); }); }); diff --git a/src/dom/Draggable.js b/src/dom/Draggable.js index 81a950ed..7356b8b9 100644 --- a/src/dom/Draggable.js +++ b/src/dom/Draggable.js @@ -16,6 +16,13 @@ L.Draggable = L.Evented.extend({ + options: { + // @option clickTolerance: Number = 3 + // The max number of pixels a user can shift the mouse pointer during a click + // for it to be considered a valid click (as opposed to a mouse drag). + clickTolerance: 3 + }, + statics: { START: L.Browser.touch ? ['touchstart', 'mousedown'] : ['mousedown'], END: { @@ -88,8 +95,8 @@ L.Draggable = L.Evented.extend({ this._startPos = this._newPos = L.DomUtil.getPosition(this._element); L.DomEvent - .on(document, L.Draggable.MOVE[e.type], this._onMove, this) - .on(document, L.Draggable.END[e.type], this._onUp, this); + .on(document, L.Draggable.MOVE[e.type], this._onMove, this) + .on(document, L.Draggable.END[e.type], this._onUp, this); }, _onMove: function (e) { @@ -103,7 +110,7 @@ L.Draggable = L.Evented.extend({ offset = newPoint.subtract(this._startPoint); if (!offset.x && !offset.y) { return; } - if (L.Browser.touch && Math.abs(offset.x) + Math.abs(offset.y) < 3) { return; } + if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { return; } L.DomEvent.preventDefault(e); @@ -158,8 +165,8 @@ L.Draggable = L.Evented.extend({ for (var i in L.Draggable.MOVE) { L.DomEvent - .off(document, L.Draggable.MOVE[i], this._onMove, this) - .off(document, L.Draggable.END[i], this._onUp, this); + .off(document, L.Draggable.MOVE[i], this._onMove, this) + .off(document, L.Draggable.END[i], this._onUp, this); } L.DomUtil.enableImageDrag();