From 4cfd3689ad2f096a01f7522824637d74ef43b9b9 Mon Sep 17 00:00:00 2001 From: "PREDATOR-STIJN\\stijn" Date: Sun, 14 Feb 2021 20:18:26 +0100 Subject: [PATCH 1/2] Add mode config to the resize circle edit mode --- docs/api-reference/modes/overview.md | 9 ++- examples/advanced/src/example.tsx | 3 + .../edit-modes/src/lib/resize-circle-mode.ts | 80 +++++++++++++------ 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/docs/api-reference/modes/overview.md b/docs/api-reference/modes/overview.md index e418a90d0..d4ca3bdf4 100644 --- a/docs/api-reference/modes/overview.md +++ b/docs/api-reference/modes/overview.md @@ -75,7 +75,14 @@ The following options can be provided in the `modeConfig` object: ## [ResizeCircleMode](https://github.com/uber/nebula.gl/blob/master/modules/edit-modes/src/lib/resize-circle-mode.js) -User can resize an existing circular Polygon feature by clicking and dragging along the ring. +User can resize an existing circular Polygon feature by clicking along the ring. + +### ModeConfig + +The following options can be provided in the `modeConfig` object: + +- `dragToDraw` (optional): `boolean` + - If `true`, user can click and drag instead of clicking twice. Note however, that the user will not be able to pan the map while drawing. ## [DrawPolygonMode](https://github.com/uber/nebula.gl/blob/master/modules/edit-modes/src/lib/draw-polygon-mode.js) diff --git a/examples/advanced/src/example.tsx b/examples/advanced/src/example.tsx index 667abbea5..a49fb9e16 100644 --- a/examples/advanced/src/example.tsx +++ b/examples/advanced/src/example.tsx @@ -606,6 +606,9 @@ export default class Example extends React.Component< if (this.state.mode === MeasureDistanceMode) { controls.push(this._renderMeasureDistanceControls()); } + if (this.state.mode === ResizeCircleMode) { + controls.push(this._renderTwoClickPolygonControls()); + } return controls; } diff --git a/modules/edit-modes/src/lib/resize-circle-mode.ts b/modules/edit-modes/src/lib/resize-circle-mode.ts index d833091d7..c4f61269d 100644 --- a/modules/edit-modes/src/lib/resize-circle-mode.ts +++ b/modules/edit-modes/src/lib/resize-circle-mode.ts @@ -10,8 +10,9 @@ import { getPickedEditHandle, NearestPointType, } from '../utils'; -import { LineString, Point, FeatureCollection, FeatureOf } from '../geojson-types'; +import { LineString, Point, Position, FeatureCollection, FeatureOf } from '../geojson-types'; import { + ClickEvent, ModeProps, PointerMoveEvent, StartDraggingEvent, @@ -128,6 +129,10 @@ export class ResizeCircleMode extends GeoJsonEditMode { } handleDragging(event: DraggingEvent, props: ModeProps): void { + if (props.modeConfig && !props.modeConfig.dragToDraw) { + return; + } + const editHandle = getPickedEditHandle(event.pointerDownPicks); if (editHandle) { @@ -135,32 +140,35 @@ export class ResizeCircleMode extends GeoJsonEditMode { event.cancelPan(); const editHandleProperties = editHandle.properties; + const featureIndex = editHandleProperties.featureIndex; + const pointerPosition = event.mapCoords; + this.drawCircle(featureIndex, pointerPosition, props); + } + } + + handleClick(event: ClickEvent, props: ModeProps) { + if (props.modeConfig && props.modeConfig.dragToDraw) { + // handled in drag handlers + return; + } - const feature = this.getSelectedFeature(props); - const center = turfCenter(feature).geometry.coordinates; - const numberOfSteps = Object.entries(feature.geometry.coordinates[0]).length - 1; - const radius = Math.max(distance(center, event.mapCoords), 0.001); - - const { steps = numberOfSteps } = {}; - const options = { steps }; - const updatedFeature = circle(center, radius, options); - const geometry = updatedFeature.geometry; - - const updatedData = new ImmutableFeatureCollection(props.data) - .replaceGeometry(editHandleProperties.featureIndex, geometry) - .getObject(); - - props.onEdit({ - updatedData, - editType: 'unionGeometry', - editContext: { - featureIndexes: [editHandleProperties.featureIndex], - }, - }); + this.addClickSequence(event); + const clickSequence = this.getClickSequence(); + if (clickSequence.length > 1) { + this._isResizing = false; + this.resetClickSequence(); + } else { + this._isResizing = true; } } handlePointerMove(event: PointerMoveEvent, props: ModeProps): void { + if (props.modeConfig && !props.modeConfig.dragToDraw && this._isResizing) { + const featureIndex = props.selectedIndexes[0]; + const pointerPosition = event.mapCoords; + this.drawCircle(featureIndex, pointerPosition, props); + } + if (!this._isResizing) { const selectedEditHandle = getPickedEditHandle(event.picks); this._selectedEditHandle = @@ -174,13 +182,13 @@ export class ResizeCircleMode extends GeoJsonEditMode { } handleStartDragging(event: StartDraggingEvent, props: ModeProps) { - if (this._selectedEditHandle) { + if (props.modeConfig && props.modeConfig.dragToDraw && this._selectedEditHandle) { this._isResizing = true; } } handleStopDragging(event: StopDraggingEvent, props: ModeProps) { - if (this._isResizing) { + if (props.modeConfig && props.modeConfig.dragToDraw && this._isResizing) { this._selectedEditHandle = null; this._isResizing = false; } @@ -195,4 +203,28 @@ export class ResizeCircleMode extends GeoJsonEditMode { } return null; } + + drawCircle(featureIndex: number, pointerPosition: Position, props: ModeProps) { + const feature = this.getSelectedFeature(props); + const center = turfCenter(feature).geometry.coordinates; + const numberOfSteps = Object.entries(feature.geometry.coordinates[0]).length - 1; + const radius = Math.max(distance(center, pointerPosition), 0.001); + + const { steps = numberOfSteps } = {}; + const options = { steps }; + const updatedFeature = circle(center, radius, options); + const geometry = updatedFeature.geometry; + + const updatedData = new ImmutableFeatureCollection(props.data) + .replaceGeometry(featureIndex, geometry) + .getObject(); + + props.onEdit({ + updatedData, + editType: 'unionGeometry', + editContext: { + featureIndexes: [featureIndex], + }, + }); + } } From 8e3bd5fe8b523ac63f427dd120774970e6e46cda Mon Sep 17 00:00:00 2001 From: "PREDATOR-STIJN\\stijn" Date: Thu, 18 Feb 2021 18:16:00 +0100 Subject: [PATCH 2/2] Fix cursor issue when resizing an existing circle by using the two click mode --- modules/edit-modes/src/lib/resize-circle-mode.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/edit-modes/src/lib/resize-circle-mode.ts b/modules/edit-modes/src/lib/resize-circle-mode.ts index c4f61269d..52b0e9fa2 100644 --- a/modules/edit-modes/src/lib/resize-circle-mode.ts +++ b/modules/edit-modes/src/lib/resize-circle-mode.ts @@ -177,7 +177,7 @@ export class ResizeCircleMode extends GeoJsonEditMode { : null; } - const cursor = this.getCursor(event); + const cursor = this.getCursor(event, props); props.onUpdateCursor(cursor); } @@ -194,11 +194,16 @@ export class ResizeCircleMode extends GeoJsonEditMode { } } - getCursor(event: PointerMoveEvent): string | null | undefined { + getCursor( + event: PointerMoveEvent, + props: ModeProps + ): string | null | undefined { const picks = (event && event.picks) || []; const handlesPicked = getPickedEditHandles(picks); - if (handlesPicked.length) { + const isResizingByClickingTwice = + props.modeConfig && !props.modeConfig.dragToDraw && this._isResizing; + if (handlesPicked.length || isResizingByClickingTwice) { return 'cell'; } return null;