diff --git a/src/ol/interaction/draw.js b/src/ol/interaction/draw.js index ad688a2c86..c0f05454c4 100644 --- a/src/ol/interaction/draw.js +++ b/src/ol/interaction/draw.js @@ -290,30 +290,25 @@ ol.interaction.Draw.prototype.setMap = function(map) { /** * Handles the {@link ol.MapBrowserEvent map browser event} and may actually * draw or finish the drawing. - * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event. + * @param {ol.MapBrowserEvent} event Map browser event. * @return {boolean} `false` to stop event propagation. * @this {ol.interaction.Draw} * @api */ -ol.interaction.Draw.handleEvent = function(mapBrowserEvent) { - if ((this.mode_ === ol.interaction.Draw.Mode.LINE_STRING || - this.mode_ === ol.interaction.Draw.Mode.POLYGON || - this.mode_ === ol.interaction.Draw.Mode.CIRCLE) && - this.freehandCondition_(mapBrowserEvent)) { - this.freehand_ = true; - } +ol.interaction.Draw.handleEvent = function(event) { + this.freehand_ = this.mode_ !== ol.interaction.Draw.Mode.POINT && this.freehandCondition_(event); var pass = !this.freehand_; if (this.freehand_ && - mapBrowserEvent.type === ol.MapBrowserEvent.EventType.POINTERDRAG && this.sketchFeature_ !== null) { - this.addToDrawing_(mapBrowserEvent); + event.type === ol.MapBrowserEvent.EventType.POINTERDRAG && this.sketchFeature_ !== null) { + this.addToDrawing_(event); pass = false; - } else if (mapBrowserEvent.type === + } else if (event.type === ol.MapBrowserEvent.EventType.POINTERMOVE) { - pass = this.handlePointerMove_(mapBrowserEvent); - } else if (mapBrowserEvent.type === ol.MapBrowserEvent.EventType.DBLCLICK) { + pass = this.handlePointerMove_(event); + } else if (event.type === ol.MapBrowserEvent.EventType.DBLCLICK) { pass = false; } - return ol.interaction.Pointer.handleEvent.call(this, mapBrowserEvent) && pass; + return ol.interaction.Pointer.handleEvent.call(this, event) && pass; }; @@ -352,15 +347,9 @@ ol.interaction.Draw.handleUpEvent_ = function(event) { var dy = downPx[1] - clickPx[1]; var squaredDistance = dx * dx + dy * dy; var pass = true; - var shouldHandle = false; - if (this.freehand_ && squaredDistance > this.squaredClickTolerance_) { - shouldHandle = this.mode_ === ol.interaction.Draw.Mode.CIRCLE || - (this.mode_ === ol.interaction.Draw.Mode.LINE_STRING && this.sketchCoords_.length >= this.maxPoints_) || - (this.mode_ === ol.interaction.Draw.Mode.POLYGON && this.sketchCoords_[0].length >= this.maxPoints_); - } else { - shouldHandle = squaredDistance <= this.squaredClickTolerance_; - } - this.freehand_ = false; + var shouldHandle = this.freehand_ ? + squaredDistance > this.squaredClickTolerance_ : + squaredDistance <= this.squaredClickTolerance_; if (shouldHandle) { this.handlePointerMove_(event); if (!this.finishCoordinate_) { @@ -368,7 +357,7 @@ ol.interaction.Draw.handleUpEvent_ = function(event) { if (this.mode_ === ol.interaction.Draw.Mode.POINT) { this.finishDrawing(); } - } else if (this.mode_ === ol.interaction.Draw.Mode.CIRCLE) { + } else if (this.freehand_ || this.mode_ === ol.interaction.Draw.Mode.CIRCLE) { this.finishDrawing(); } else if (this.atFinish_(event)) { if (this.finishCondition_(event)) { @@ -426,8 +415,7 @@ ol.interaction.Draw.prototype.atFinish_ = function(event) { var pixel = event.pixel; var dx = pixel[0] - finishPixel[0]; var dy = pixel[1] - finishPixel[1]; - var freehand = this.freehand_ && this.freehandCondition_(event); - var snapTolerance = freehand ? 1 : this.snapTolerance_; + var snapTolerance = this.freehand_ ? 1 : this.snapTolerance_; at = Math.sqrt(dx * dx + dy * dy) <= snapTolerance; if (at) { this.finishCoordinate_ = finishCoordinate; diff --git a/test/spec/ol/interaction/draw.test.js b/test/spec/ol/interaction/draw.test.js index 57c10c1111..78ef2b996c 100644 --- a/test/spec/ol/interaction/draw.test.js +++ b/test/spec/ol/interaction/draw.test.js @@ -299,11 +299,6 @@ describe('ol.interaction.Draw', function() { simulateEvent('pointerdrag', 20, 40, true); simulateEvent('pointerup', 20, 40, true); - // finish on third point - simulateEvent('pointermove', 20, 40); - simulateEvent('pointerdown', 20, 40); - simulateEvent('pointerup', 20, 40); - var features = source.getFeatures(); expect(features).to.have.length(1); var geometry = features[0].getGeometry(); @@ -312,6 +307,43 @@ describe('ol.interaction.Draw', function() { [[10, -20], [20, -30], [20, -40]]); }); + it('allows freehand mode for part of the drawing', function() { + + // non-freehand + simulateEvent('pointerdown', 10, 20); + simulateEvent('pointerup', 10, 20); + simulateEvent('pointermove', 20, 30); + + // freehand + simulateEvent('pointerdown', 20, 30, true); + simulateEvent('pointermove', 20, 30, true); + simulateEvent('pointerdrag', 20, 30, true); + simulateEvent('pointermove', 30, 40, true); + simulateEvent('pointerdrag', 30, 40, true); + simulateEvent('pointermove', 40, 50, true); + simulateEvent('pointerdrag', 40, 50, true); + + // non-freehand + simulateEvent('pointerup', 40, 50); + simulateEvent('pointermove', 50, 60); + simulateEvent('pointerdown', 50, 60); + simulateEvent('pointerup', 50, 60); + simulateEvent('pointermove', 60, 70); + simulateEvent('pointerdown', 60, 70); + simulateEvent('pointerup', 60, 70); + + // finish + simulateEvent('pointerdown', 60, 70); + simulateEvent('pointerup', 60, 70); + + var features = source.getFeatures(); + // expect(features).to.have.length(1); + var geometry = features[0].getGeometry(); + expect(geometry).to.be.a(ol.geom.LineString); + expect(geometry.getCoordinates()).to.eql( + [[10, -20], [20, -30], [30, -40], [40, -50], [50, -60], [60, -70]]); + }); + it('does not add a point with a significant drag', function() { // first point simulateEvent('pointermove', 10, 20);