Skip to content

Commit

Permalink
react-map-gl-draw: customized modes (#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xintong Xia committed Apr 3, 2020
1 parent 28bf175 commit d6ef889
Show file tree
Hide file tree
Showing 20 changed files with 426 additions and 470 deletions.
29 changes: 29 additions & 0 deletions dev-docs/RFCs/v1.0/customized-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# [MiniRFC] react-map-gl-draw: Support customized modes

- **Authors**: Xintong Xia
- **Date**: March 2020
- **Status**: Draft


## Summary

`react-map-gl-draw` gets more and more public interests, some users requested new drawing modes, i.e. drawing circle,
some want to customize drawing and editing behaviors, i.e. disable dragging while editing, drawing rectangle without releasing mouse.
Current API is not scalable to support customizations. Additionally Nebula.gl already support customized modes.

## Proposal

Change the options `mode` type to be a `ModeHandler` object. And expose all the existing modes, and a method to allow user re-deregister events.

- `mode` (Object, Optional)
- default to `null`

- `EditorModes.SELECT` - Lets you select features.
- `EditorModes.EDITTING` - Lets you select and drag vertices; and drag features.
- `EditorModes.DRAW_PATH` - Lets you draw a GeoJson `LineString` feature.
- `EditorModes.DRAW_POLYGON` - Lets you draw a GeoJson `Polygon` feature.
- `EditorModes.DRAW_POINT` - Lets you draw a GeoJson `Point` feature.
- `EditorModes.DRAW_RECTANGLE` - Lets you draw a `Rectangle` (represented as GeoJson `Polygon` feature) with two clicks - start drawing on first click, and finish drawing on second click .
- `EditorModes.DRAW_RECTANGLE_ONE_CLICK` - Lets you draw a `Rectangle` (represented as GeoJson `Polygon` feature) with one click - start drawing when mouse down and finish drawing when mouse released.

Customized edit mode should follow [BaseMode](https://github.com/uber/nebula.gl/blob/master/modules/react-map-gl-draw/src/edit-modes/base-mode.js)
2 changes: 1 addition & 1 deletion docs/api-reference/react-map-gl-draw/react-map-gl-draw.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
`react-map-gl-draw` is a react based drawing library tailored for [`react-map-gl`](https://github.com/uber/react-map-gl).

## Options
- `mode` (String, Optional)
- `mode` (Object, Optional)
- `EditorModes.READ_ONLY` - Not interactive. This is the default mode.
- `EditorModes.SELECT` - Lets you select, delete, and drag features.
- `EditorModes.EDITTING` - Lets you select, delete, and drag vertices; and drag features.
Expand Down
34 changes: 28 additions & 6 deletions examples/react-map-gl-draw/app.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import React, { Component } from 'react';
import { render } from 'react-dom';
import MapGL from 'react-map-gl';
import { Editor, EditorModes } from 'react-map-gl-draw';

import {
Editor,
SelectMode,
EditingMode,
DrawPointMode,
DrawLineStringMode,
DrawRectangleMode,
DrawRectangleOneclickMode,
DrawPolygonMode
} from 'react-map-gl-draw';
import { MODES } from './constants';
import Toolbar from './toolbar';

const MODE_TO_HANDLER = {
[MODES.READ_ONLY]: null,
[MODES.SELECT]: SelectMode,
[MODES.EDITING]: EditingMode,
[MODES.DRAW_POINT]: DrawPointMode,
[MODES.DRAW_PATH]: DrawLineStringMode,
[MODES.DRAW_RECTANGLE]: DrawRectangleMode,
[MODES.DRAW_RECTANGLE_ONE_CLICK]: DrawRectangleOneclickMode,
[MODES.DRAW_POLYGON]: DrawPolygonMode
};

// eslint-disable-next-line no-process-env, no-undef
const MAP_STYLE = process.env.MapStyle || 'mapbox://styles/mapbox/light-v9';

Expand All @@ -23,7 +43,7 @@ export default class App extends Component {
// map
viewport: DEFAULT_VIEWPORT,
// editor
selectedMode: EditorModes.READ_ONLY,
selectedMode: null,
selectedFeatureIndex: null
};
this._editorRef = null;
Expand All @@ -44,7 +64,9 @@ export default class App extends Component {
selectedMode = null;
}

this.setState({ selectedMode });
const HandlerClass = MODE_TO_HANDLER[selectedMode];
const modeHandler = HandlerClass ? new HandlerClass() : null;
this.setState({ selectedMode, modeHandler });
};

_updateViewport = viewport => {
Expand All @@ -62,7 +84,7 @@ export default class App extends Component {
};

render() {
const { viewport, selectedMode } = this.state;
const { viewport, modeHandler } = this.state;
return (
<MapGL
{...viewport}
Expand All @@ -77,7 +99,7 @@ export default class App extends Component {
onSelect={selected => {
this.setState({ selectedFeatureIndex: selected && selected.selectedFeatureIndex });
}}
mode={selectedMode}
mode={modeHandler}
/>
{this._renderToolbar()}
</MapGL>
Expand Down
11 changes: 11 additions & 0 deletions examples/react-map-gl-draw/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const MODES = {
READ_ONLY: 'READ_ONLY',
SELECT: 'SELECT',
EDITING: 'EDITING',
DRAW_POINT: 'DRAW_POINT',
DRAW_CIRCLE: 'DRAW_CIRCLE',
DRAW_PATH: 'DRAW_PATH',
DRAW_POLYGON: 'DRAW_POLYGON',
DRAW_RECTANGLE: 'DRAW_RECTANGLE',
DRAW_RECTANGLE_ONE_CLICK: 'DRAW_RECTANGLE_ONE_CLICK'
};
3 changes: 2 additions & 1 deletion examples/react-map-gl-draw/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"react": "^16.3.0",
"react-dom": "^16.3.0",
"react-map-gl": "^4.0.0",
"react-map-gl-draw": "^0.14.0"
"react-map-gl-draw": "^0.14.0",
"@math.gl/core": "^3.1.3"
},
"devDependencies": {
"@babel/core": "^7.0.0",
Expand Down
22 changes: 14 additions & 8 deletions examples/react-map-gl-draw/toolbar.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
/* global setTimeout */
import React, { PureComponent } from 'react';
import styled from 'styled-components';
import { EditorModes } from 'react-map-gl-draw';

const MODES = [
{ id: EditorModes.EDITING, text: 'Edit Feature', icon: 'icon-select.svg' },
{ id: EditorModes.DRAW_POINT, text: 'Draw Point', icon: 'icon-point.svg' },
{ id: EditorModes.DRAW_PATH, text: 'Draw Polyline', icon: 'icon-path.svg' },
{ id: EditorModes.DRAW_POLYGON, text: 'Draw Polygon', icon: 'icon-polygon.svg' },
{ id: EditorModes.DRAW_RECTANGLE, text: 'Draw Rectangle', icon: 'icon-rectangle.svg' }
import { MODES } from './constants';

const ICON_MAP = [
{ id: MODES.EDITING, text: 'Edit Feature', icon: 'icon-select.svg' },
{ id: MODES.DRAW_POINT, text: 'Draw Point', icon: 'icon-point.svg' },
{ id: MODES.DRAW_PATH, text: 'Draw Polyline', icon: 'icon-path.svg' },
{ id: MODES.DRAW_POLYGON, text: 'Draw Polygon', icon: 'icon-polygon.svg' },
{ id: MODES.DRAW_RECTANGLE, text: 'Draw Rectangle', icon: 'icon-rectangle.svg' },
{
id: MODES.DRAW_RECTANGLE_ONE_CLICK,
text: 'Draw Rectangle (One Click)',
icon: 'icon-rectangle.svg'
}
];

const Container = styled.div`
Expand Down Expand Up @@ -89,7 +95,7 @@ export default class Toolbar extends PureComponent {

return (
<Container>
{MODES.map(m => {
{ICON_MAP.map(m => {
return (
<Row
onClick={this.props.onSwitchMode}
Expand Down
8 changes: 4 additions & 4 deletions modules/react-map-gl-draw/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
"test": "yarn lint && yarn build && yarn flow && yarn jest"
},
"dependencies": {
"@math.gl/web-mercator": "^3.1.3",
"@nebula.gl/edit-modes": "^0.17.6",
"@turf/helpers": "^6.1.4",
"mjolnir.js": "^2.2.1",
"mjolnir.js": "^2.4.0",
"prop-types": "^15.7.2",
"uuid": "^3.3.2",
"viewport-mercator-project": "^6.1.0"
"uuid": "^3.4.0"
},
"devDependencies": {
"react-map-gl": "^5.2.1"
"react-map-gl": "^5.2.3"
},
"peerDependencies": {
"react": "^16.x",
Expand Down
17 changes: 0 additions & 17 deletions modules/react-map-gl-draw/src/constants.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
// @flow

export const MODES = {
READ_ONLY: 'READ_ONLY',
SELECT: 'SELECT',
EDITING: 'EDITING',
DRAW_POINT: 'DRAW_POINT',
DRAW_PATH: 'DRAW_PATH',
DRAW_POLYGON: 'DRAW_POLYGON',
DRAW_RECTANGLE: 'DRAW_RECTANGLE'
};

export const DRAWING_MODE = [
MODES.DRAW_POINT,
MODES.DRAW_PATH,
MODES.DRAW_POLYGON,
MODES.DRAW_RECTANGLE
];

export const GEOJSON_TYPE = {
POINT: 'Point',
LINE_STRING: 'LineString',
Expand Down
2 changes: 2 additions & 0 deletions modules/react-map-gl-draw/src/edit-modes/base-mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export default class BaseMode implements EditMode<FeatureCollection, GuideFeatur
this._editHandles = null;
}

handlePan(event: ClickEvent, props: ModeProps<FeatureCollection>) {}

handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {}

handleDblClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {}
Expand Down
Loading

0 comments on commit d6ef889

Please sign in to comment.