diff --git a/docs/modules/editable-layers/api-reference/layers/editable-geojson-layer.md b/docs/modules/editable-layers/api-reference/layers/editable-geojson-layer.md index f9252d53..790fa235 100644 --- a/docs/modules/editable-layers/api-reference/layers/editable-geojson-layer.md +++ b/docs/modules/editable-layers/api-reference/layers/editable-geojson-layer.md @@ -145,6 +145,10 @@ The `onEdit` event is the core event provided by this layer and must be handled * `editContext` (Object): `null` or an object containing additional context about the edit. This is populated by the active mode. +#### `onCancelPan` (Function, optional) + +The `onCancelPan` event is called when map panning should be cancelled to enable feature dragging interactions while editing. + ### Guide style properties and data getters #### `editHandleType`: (String, optional) diff --git a/modules/editable-layers/src/edit-modes/extend-line-string-mode.ts b/modules/editable-layers/src/edit-modes/extend-line-string-mode.ts index fde20887..33f295f4 100644 --- a/modules/editable-layers/src/edit-modes/extend-line-string-mode.ts +++ b/modules/editable-layers/src/edit-modes/extend-line-string-mode.ts @@ -62,6 +62,10 @@ export class ExtendLineStringMode extends GeoJsonEditMode { const mapCoords = props.lastPointerMoveEvent && props.lastPointerMoveEvent.mapCoords; + if (!mapCoords) { + return guides; + } + // Draw an extension line starting from one end of the selected LineString to the cursor let startPosition: Position | null | undefined = null; const {modeConfig} = props; diff --git a/modules/editable-layers/src/edit-modes/extrude-mode.ts b/modules/editable-layers/src/edit-modes/extrude-mode.ts index 41d638ac..f1d827ca 100644 --- a/modules/editable-layers/src/edit-modes/extrude-mode.ts +++ b/modules/editable-layers/src/edit-modes/extrude-mode.ts @@ -6,7 +6,8 @@ import bearing from '@turf/bearing'; import { generatePointsParallelToLinePoints, getPickedEditHandle, - getPickedIntermediateEditHandle + getPickedIntermediateEditHandle, + shouldCancelPan } from './utils'; import {FeatureCollection} from '../utils/geojson-types'; import {ModeProps, StartDraggingEvent, StopDraggingEvent, DraggingEvent} from './types'; @@ -61,6 +62,10 @@ export class ExtrudeMode extends ModifyMode { } handleStartDragging(event: StartDraggingEvent, props: ModeProps) { + if (shouldCancelPan(event)) { + event.cancelPan(); + } + const selectedFeatureIndexes = props.selectedIndexes; const editHandle = getPickedIntermediateEditHandle(event.picks); diff --git a/modules/editable-layers/src/edit-modes/modify-mode.ts b/modules/editable-layers/src/edit-modes/modify-mode.ts index 021ac2f4..72f84e61 100644 --- a/modules/editable-layers/src/edit-modes/modify-mode.ts +++ b/modules/editable-layers/src/edit-modes/modify-mode.ts @@ -13,7 +13,8 @@ import { getPickedExistingEditHandle, getPickedIntermediateEditHandle, updateRectanglePosition, - NearestPointType + NearestPointType, + shouldCancelPan } from './utils'; import {LineString, Point, Polygon, FeatureCollection, FeatureOf} from '../utils/geojson-types'; import { @@ -251,6 +252,10 @@ export class ModifyMode extends GeoJsonEditMode { } handleStartDragging(event: StartDraggingEvent, props: ModeProps) { + if (shouldCancelPan(event)) { + event.cancelPan(); + } + const selectedFeatureIndexes = props.selectedIndexes; const editHandle = getPickedIntermediateEditHandle(event.picks); diff --git a/modules/editable-layers/src/edit-modes/resize-circle-mode.ts b/modules/editable-layers/src/edit-modes/resize-circle-mode.ts index b4c1a101..95d94908 100644 --- a/modules/editable-layers/src/edit-modes/resize-circle-mode.ts +++ b/modules/editable-layers/src/edit-modes/resize-circle-mode.ts @@ -182,6 +182,7 @@ export class ResizeCircleMode extends GeoJsonEditMode { handleStartDragging(event: StartDraggingEvent, props: ModeProps) { if (this._selectedEditHandle) { + event.cancelPan(); this._isResizing = true; } } diff --git a/modules/editable-layers/src/edit-modes/rotate-mode.ts b/modules/editable-layers/src/edit-modes/rotate-mode.ts index 599f966b..cbb110f2 100644 --- a/modules/editable-layers/src/edit-modes/rotate-mode.ts +++ b/modules/editable-layers/src/edit-modes/rotate-mode.ts @@ -128,6 +128,7 @@ export class RotateMode extends GeoJsonEditMode { handleStartDragging(event: StartDraggingEvent, props: ModeProps) { if (this._selectedEditHandle) { + event.cancelPan(); this._isRotating = true; this._geometryBeingRotated = this.getSelectedFeaturesAsFeatureCollection(props); } diff --git a/modules/editable-layers/src/edit-modes/scale-mode.ts b/modules/editable-layers/src/edit-modes/scale-mode.ts index 090dedae..53366d90 100644 --- a/modules/editable-layers/src/edit-modes/scale-mode.ts +++ b/modules/editable-layers/src/edit-modes/scale-mode.ts @@ -152,6 +152,7 @@ export class ScaleMode extends GeoJsonEditMode { handleStartDragging(event: StartDraggingEvent, props: ModeProps) { if (this._selectedEditHandle) { + event.cancelPan(); this._isScaling = true; this._geometryBeingScaled = this.getSelectedFeaturesAsFeatureCollection(props); } diff --git a/modules/editable-layers/src/edit-modes/transform-mode.ts b/modules/editable-layers/src/edit-modes/transform-mode.ts index d6b02a94..04ca0215 100644 --- a/modules/editable-layers/src/edit-modes/transform-mode.ts +++ b/modules/editable-layers/src/edit-modes/transform-mode.ts @@ -33,6 +33,10 @@ export class TransformMode extends CompositeMode { let translateMode: TranslateMode | null = null; const filteredModes: GeoJsonEditMode[] = []; + if (event.picks.length) { + event.cancelPan(); + } + // If the user selects a scaling edit handle that overlaps with part of the selected feature, // it is possible for both scale and translate actions to be triggered. This logic prevents // this simultaneous action trigger from happening by putting a higher priority on scaling diff --git a/modules/editable-layers/src/edit-modes/translate-mode.ts b/modules/editable-layers/src/edit-modes/translate-mode.ts index fd42637c..d1a61211 100644 --- a/modules/editable-layers/src/edit-modes/translate-mode.ts +++ b/modules/editable-layers/src/edit-modes/translate-mode.ts @@ -59,6 +59,7 @@ export class TranslateMode extends GeoJsonEditMode { return; } + event.cancelPan(); this._geometryBeforeTranslate = this.getSelectedFeaturesAsFeatureCollection(props); } diff --git a/modules/editable-layers/src/edit-modes/types.ts b/modules/editable-layers/src/edit-modes/types.ts index c281540f..ed49aa5d 100644 --- a/modules/editable-layers/src/edit-modes/types.ts +++ b/modules/editable-layers/src/edit-modes/types.ts @@ -18,6 +18,7 @@ export type Pick = { index: number; object?: any; isGuide?: boolean; + featureType?: string; featureIndex?: number; type?: string; isEditingHandle?: boolean | null; diff --git a/modules/editable-layers/src/edit-modes/utils.ts b/modules/editable-layers/src/edit-modes/utils.ts index fffb71c8..0dae0e56 100644 --- a/modules/editable-layers/src/edit-modes/utils.ts +++ b/modules/editable-layers/src/edit-modes/utils.ts @@ -11,7 +11,7 @@ import {flattenEach} from '@turf/meta'; import {point, MultiLineString} from '@turf/helpers'; import {getCoords} from '@turf/invariant'; import WebMercatorViewport from 'viewport-mercator-project'; -import {Viewport, Pick, EditHandleFeature, EditHandleType} from './types'; +import {Viewport, Pick, EditHandleFeature, EditHandleType, StartDraggingEvent} from './types'; import { Geometry, Position, @@ -516,3 +516,7 @@ export function mapCoords( }) .filter(Boolean); } + +export function shouldCancelPan(event: StartDraggingEvent) { + return event.picks.length && event.picks.find((p) => p.featureType === 'points'); +} diff --git a/modules/editable-layers/src/editable-layers/editable-layer.ts b/modules/editable-layers/src/editable-layers/editable-layer.ts index 80478a56..080575da 100644 --- a/modules/editable-layers/src/editable-layers/editable-layer.ts +++ b/modules/editable-layers/src/editable-layers/editable-layer.ts @@ -20,6 +20,7 @@ const EVENT_TYPES = ['anyclick', 'pointermove', 'panstart', 'panmove', 'panend', export type EditableLayerProps = CompositeLayerProps & { pickingRadius?: number; pickingDepth?: number; + onCancelPan?: () => void; }; export abstract class EditableLayer< @@ -154,7 +155,13 @@ export abstract class EditableLayer< mapCoords, pointerDownScreenCoords: screenCoords, pointerDownMapCoords: mapCoords, - cancelPan: event.stopImmediatePropagation, + cancelPan: () => { + if (this.props.onCancelPan) { + this.props.onCancelPan(); + } + + event.stopImmediatePropagation(); + }, sourceEvent: event.srcEvent }); }