From 51b003cc2db2cc7344a4ed3d555ef64c16076cf9 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Mon, 13 Oct 2025 14:17:43 +0800 Subject: [PATCH] Circle/Ellipse/Rectangle draw adapt to SnapTo --- packages/maptalks/src/map/tool/DrawTool.ts | 37 ++++++++++++++----- .../maptalks/src/map/tool/DrawToolRegister.ts | 7 +++- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/packages/maptalks/src/map/tool/DrawTool.ts b/packages/maptalks/src/map/tool/DrawTool.ts index 31db9b8730..e4dbd8de7a 100644 --- a/packages/maptalks/src/map/tool/DrawTool.ts +++ b/packages/maptalks/src/map/tool/DrawTool.ts @@ -438,7 +438,7 @@ class DrawTool extends MapTool { if (Array.isArray(action)) { for (let i = 0; i < action.length; i++) { //@internal - _events[action[i]] = this._events[action[i]]; + _events[action[i]] = this._events[action[i]]; } return _events; } @@ -455,7 +455,7 @@ class DrawTool extends MapTool { */ //@internal _mouseDownHandler(event: any) { - if(!event?.coordinate) { + if (!event?.coordinate) { return } this._createGeometry(event); @@ -471,12 +471,21 @@ class DrawTool extends MapTool { */ //@internal _mouseUpHandler(event: any) { - if(!event?.coordinate) { + if (!event?.coordinate) { return } this.endDraw(event); } + _copyMapEventOnSnapTo(mapEvent, prjCoord) { + const map = this.getMap(); + if (!map) { + return mapEvent; + } + return Object.assign({}, mapEvent, { containerPoint: map.prjToContainerPoint(prjCoord) }) + } + + /** * 监听mouse first click点击事件 * @@ -487,7 +496,7 @@ class DrawTool extends MapTool { */ //@internal _clickHandler(event: any) { - if(!event?.coordinate) { + if (!event?.coordinate) { return } if (!this.options.interactive) { @@ -514,9 +523,11 @@ class DrawTool extends MapTool { } //for snap effect const snapTo = this._geometry.snapTo; + let copyEvent; if (snapTo && isFunction(snapTo)) { const snapResult = this._getSnapResult(snapTo, event.containerPoint); prjCoord = snapResult.prjCoord; + copyEvent = this._copyMapEventOnSnapTo(event, prjCoord); this._clickCoords = this._clickCoords.concat(snapResult.effectedVertex); // ensure snap won't trigger again when dblclick if (this._clickCoords[this._clickCoords.length - 1].equals(prjCoord)) { @@ -526,7 +537,7 @@ class DrawTool extends MapTool { this._clickCoords.push(prjCoord); this._historyPointer = this._clickCoords.length; event.drawTool = this; - registerMode['update'](map.getProjection(), this._clickCoords, this._geometry, event); + registerMode['update'](map.getProjection(), this._clickCoords, this._geometry, copyEvent || event); if (this.getMode() === 'point') { this.endDraw(event); return; @@ -624,7 +635,11 @@ class DrawTool extends MapTool { if (map && snapResult) { const prjCoord = snapResult.prjCoord; this._clickCoords = [prjCoord]; - registerMode['update'](map.getProjection(), this._clickCoords, this._geometry, event); + if (this._geometry._firstClick) { + this._geometry._firstClick = prjCoord; + } + const copyEvent = this._copyMapEventOnSnapTo(event, prjCoord); + registerMode['update'](map.getProjection(), this._clickCoords, this._geometry, copyEvent); } } } @@ -644,7 +659,7 @@ class DrawTool extends MapTool { */ //@internal _mouseMoveHandler(event) { - if(!event?.coordinate) { + if (!event?.coordinate) { return } if (!this.options.interactive) { @@ -670,10 +685,12 @@ class DrawTool extends MapTool { // for snap effect let snapAdditionVertex = []; const snapTo = this._geometry.snapTo; + let copyEvent; if (snapTo && isFunction(snapTo)) { const snapResult = this._getSnapResult(snapTo, containerPoint); prjCoord = snapResult.prjCoord; snapAdditionVertex = snapResult.effectedVertex; + copyEvent = this._copyMapEventOnSnapTo(event, prjCoord); } const projection = map.getProjection(); event.drawTool = this; @@ -683,10 +700,10 @@ class DrawTool extends MapTool { if (path && path.length > 0 && prjCoord.equals(path[path.length - 1])) { return; } - registerMode['update'](projection, path.concat(snapAdditionVertex, [prjCoord]), this._geometry, event); + registerMode['update'](projection, path.concat(snapAdditionVertex, [prjCoord]), this._geometry, copyEvent || event); } else { //free hand mode - registerMode['update'](projection, prjCoord, this._geometry, event); + registerMode['update'](projection, prjCoord, this._geometry, copyEvent || event); } /** * mousemove事件 @@ -717,7 +734,7 @@ class DrawTool extends MapTool { */ //@internal _doubleClickHandler(event) { - if(!event?.coordinate) { + if (!event?.coordinate) { return } if (!this.options.interactive) { diff --git a/packages/maptalks/src/map/tool/DrawToolRegister.ts b/packages/maptalks/src/map/tool/DrawToolRegister.ts index 6abf7223c6..5a463f91b3 100644 --- a/packages/maptalks/src/map/tool/DrawToolRegister.ts +++ b/packages/maptalks/src/map/tool/DrawToolRegister.ts @@ -70,15 +70,20 @@ const circleHooks: modeActionType = { // const center = projection.unproject(prjCoord[0]); const center = queryTerrainCoordinates(projection, prjCoord[0], mapEvent); const circle: Circle = new Circle(center as Coordinate, 0); + (circle as any)._firstClick = prjCoord[0]; // circle._setPrjCoordinates(prjCoord[0]); return circle; }, 'update': function (projection, prjPath, geometry, mapEvent) { + let center = geometry.getCenter(); + if (geometry._firstClick) { + center = queryTerrainCoordinates(projection, geometry._firstClick, mapEvent); + } const map = geometry.getMap(); const prjCoord = Array.isArray(prjPath) ? prjPath[prjPath.length - 1] : prjPath; // const nextCoord = projection.unproject(prjCoord); const nextCoord = queryTerrainCoordinates(projection, prjCoord, mapEvent); - const radius = map.computeLength(geometry.getCenter(), nextCoord); + const radius = map.computeLength(center, nextCoord); geometry.setRadius(radius); }, 'generate': function (geometry) {