Leaflet.draw icon indicating copy to clipboard operation
Leaflet.draw copied to clipboard

Map drag during polygon draw will add point with leaflet 1.0

Open richardhinkamp opened this issue 8 years ago • 12 comments

  • Leaflet version I'm using: 1.0.3 and 0.7.2
  • Leaflet Draw version I'm using: master
  • Browser (with version) I'm using: chrome 56 / edge / ie11
  • OS/Platform (with version) I'm using: linux + windows

When using with leaflet 0.7.x you can move the map by dragging while drawing a polygon. With leaflet 1 you can also drag the map, but it will add a point where you click to start the drag.

Steps:

  • Start drawing a polygon
  • Click to add a point
  • Drag the map (mouse down, move, mouse up)

With leaflet 0.7 it will just to the drag, with leaflet 1 it will also add a point on the mouse down. I think the behaviour with 0.7 is the desired one.

See examples https://leaflet.github.io/Leaflet.draw/docs/examples/full.html and https://leaflet.github.io/Leaflet.draw/docs/examples-0.7.x/full.html

richardhinkamp avatar Feb 17 '17 16:02 richardhinkamp

This example has the correct behavior with Leaflet 1.0.1+ffcfcc1 https://b3ncr.github.io/docs/examples/full.html but is version 0.4.2 (But seems to has the 0.4.9 polyline fix)

McCABRUS avatar Feb 20 '17 14:02 McCABRUS

The problem is in L.Draw.Polyline._onTouch. This simulates mouse down+up so directly adding a new point. This should not work on just touchstart, but on touchstart+touchend like mousedown+mouseup I guess. I'v been looking into this but I don't see any touchend events being fired. I have no good touch device to debug the touch handling.

For now I added this hack:

(function() {
	var originalOnTouch = L.Draw.Polyline.prototype._onTouch;
	L.Draw.Polyline.prototype._onTouch = function( e ) {
		if( e.originalEvent.pointerType != 'mouse' ) {
			return originalOnTouch.call(this, e);
		}
	}
})();

So on a desktop using a mouse it doesn't handle touch events. I need get a touch device to debug the touch handling.

richardhinkamp avatar Feb 22 '17 13:02 richardhinkamp

If you are programatically enabling any drawing mode, you must put the aforementioned hack before your call to enable!

ie.
... (function() { var originalOnTouch = L.Draw.Polyline.prototype._onTouch; L.Draw.Polyline.prototype._onTouch = function( e ) { if( e.originalEvent.pointerType != 'mouse' ) { return originalOnTouch.call(this, e); } } })(); ... new L.Draw.Polygon(map, drawControl.options.polygon).enable();

Happy coding!

iredmedia avatar Apr 24 '17 03:04 iredmedia

This issue has one more very unwanted side effect. It is possible to create invalid geometry with lines only one point long. If I click on "Draw a polyline" tool, then I create a point in the map and then I click on the point once more, the point disappears. It is not visible, but in the background, there is invalid geometry, which breaks when I use it in PostGIS.

The proposed hack prevents this also. EDIT: Well, it prevents it, but only on desktop. On touchscreen, I am still able to create the one-point line.

PetrDlouhy avatar May 01 '17 14:05 PetrDlouhy

I used the solution @richardhinkamp provided, which works fantastically for allowing the map dragging without adding a node - however if my polyline revisits any of the previous nodes, I can no longer click on their noes to place the line. For example if my polyline is a loop (my project is making route cards for walks, so often loops are necessary), the line has to finish next to the start point, not over the top.

edprince avatar Aug 08 '17 10:08 edprince

The @richardhinkamp workaround works fine for desktop but unfortunately it still doesn't work for touch devices (chrome).

cosme-benito avatar Oct 23 '17 14:10 cosme-benito

If you wan't to make this to work in a mobile device too, just add:

&& e.originalEvent.pointerType != 'touch'

Modify the script to this:

(function() {
	var originalOnTouch = L.Draw.Polyline.prototype._onTouch;
	L.Draw.Polyline.prototype._onTouch = function( e ) {
		if( e.originalEvent.pointerType != 'mouse'  && e.originalEvent.pointerType != 'touch' ) {
			return originalOnTouch.call(this, e);
		}
	}
})();

mhosman avatar May 25 '18 18:05 mhosman

Simpler fix:

  L.Draw.Polyline.prototype._onTouch = L.Util.falseFn;

johnd0e avatar Jan 22 '20 12:01 johnd0e

Behaviour of this changed with some newer Leaflet version. If I try the demo which has hardwired Leaflet 1.3.1, the issue is present. But when I update the Leaflet to 1.6.0, drawing polygon/polyline on desktop works fine. But not on mobile - dragging the map still produces unwanted points. And I was not able to fix this by the suggested workarounds.

PetrDlouhy avatar May 24 '20 09:05 PetrDlouhy

And I was not able to fix this by the suggested workarounds.

Make sure that tap handler is disabled. E.g. create map with {tap: false} option.

johnd0e avatar May 24 '20 09:05 johnd0e

@johnd0e Thanks, you are right. After that everything works perfectly.

PetrDlouhy avatar May 26 '20 07:05 PetrDlouhy

The solution refers to Polyline... does this help with Polygon and Rectangle draw as well? Drawing polygon works fine and during creation you can still hold mouse down to PAN. But on rectangle the initial click is wonky and any slight drag of mouse causes it to end and create a super tiny rectangle. So that's one issue. The other issue is if you do get the rectangle draw to start... you cannot pan at all. You can zoom but you can't pan. Or at least in my app. The simple demos online dont act this way so not sure what is causing it.

torrid33 avatar Jan 11 '23 21:01 torrid33