diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 61f59ba0fb..879fcf88d2 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -956,8 +956,12 @@ export function createRegularPolygon(opt_sides, opt_angle) { squaredCoordinateDistance(center, end)); const geometry = opt_geometry ? /** @type {module:ol/geom/Polygon} */ (opt_geometry) : fromCircle(new Circle(center), opt_sides); - const angle = opt_angle ? opt_angle : - Math.atan((end[1] - center[1]) / (end[0] - center[0])); + let angle = opt_angle; + if (!opt_angle) { + const x = end[0] - center[0]; + const y = end[1] - center[1]; + angle = Math.atan(y / x) - (x < 0 ? Math.PI : 0); + } makeRegular(geometry, center, radius, angle); return geometry; }; diff --git a/test/spec/ol/interaction/draw.test.js b/test/spec/ol/interaction/draw.test.js index b2497c166f..f0b95de23e 100644 --- a/test/spec/ol/interaction/draw.test.js +++ b/test/spec/ol/interaction/draw.test.js @@ -62,6 +62,7 @@ describe('ol.interaction.Draw', function() { * @param {number} x Horizontal offset from map center. * @param {number} y Vertical offset from map center. * @param {boolean=} opt_shiftKey Shift key is pressed. + * @return {module:ol/MapBrowserPointerEvent} The simulated event. */ function simulateEvent(type, x, y, opt_shiftKey) { const viewport = map.getViewport(); @@ -72,8 +73,12 @@ describe('ol.interaction.Draw', function() { clientX: position.left + x + width / 2, clientY: position.top + y + height / 2, shiftKey: shiftKey + }, { + pointerType: 'mouse' }); - map.handleMapBrowserEvent(new MapBrowserPointerEvent(type, map, event)); + const simulatedEvent = new MapBrowserPointerEvent(type, map, event); + map.handleMapBrowserEvent(simulatedEvent); + return simulatedEvent; } describe('constructor', function() { @@ -1059,8 +1064,7 @@ describe('ol.interaction.Draw', function() { const draw = new Draw({ source: source, type: 'Circle', - geometryFunction: - createRegularPolygon(4, Math.PI / 4) + geometryFunction: createRegularPolygon(4, Math.PI / 4) }); map.addInteraction(draw); @@ -1082,6 +1086,52 @@ describe('ol.interaction.Draw', function() { expect(coordinates[0][0][0]).to.roughlyEqual(20, 1e-9); expect(coordinates[0][0][1]).to.roughlyEqual(20, 1e-9); }); + + it('sketch start point always matches the mouse point', function() { + const draw = new Draw({ + source: source, + type: 'Circle', + geometryFunction: createRegularPolygon(3) + }); + map.addInteraction(draw); + + // regular polygon center point + simulateEvent('pointermove', 60, 60); + simulateEvent('pointerdown', 60, 60); + simulateEvent('pointerup', 60, 60); + + // move to first quadrant + simulateEvent('pointermove', 79, 80); + let event = simulateEvent('pointermove', 80, 80); + let coordinate = event.coordinate; + const firstQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(firstQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(firstQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + + // move to second quadrant + simulateEvent('pointermove', 41, 80); + event = simulateEvent('pointermove', 40, 80); + coordinate = event.coordinate; + const secondQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(secondQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(secondQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + + // move to third quadrant + simulateEvent('pointermove', 40, 41); + event = simulateEvent('pointermove', 40, 40); + coordinate = event.coordinate; + const thirdQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(thirdQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(thirdQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + + // move to fourth quadrant + simulateEvent('pointermove', 79, 40); + event = simulateEvent('pointermove', 80, 40); + coordinate = event.coordinate; + const fourthQuadrantCoordinate = draw.sketchFeature_.getGeometry().getFirstCoordinate(); + expect(fourthQuadrantCoordinate[0]).to.roughlyEqual(coordinate[0], 1e-9); + expect(fourthQuadrantCoordinate[1]).to.roughlyEqual(coordinate[1], 1e-9); + }); }); describe('createBox', function() {