Skip to content

Commit

Permalink
- Added a new DragCircle mode.
Browse files Browse the repository at this point in the history
- Fixed Polygon issue (#5).
  • Loading branch information
Anvesh Arrabochu committed Aug 4, 2019
1 parent 52ae7e3 commit c12944f
Show file tree
Hide file tree
Showing 10 changed files with 393 additions and 6 deletions.
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

node_modules/
coverage/
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ Adds support for drawing and editing a circle feature using [mapbox-gl-draw](htt

## Demo

![Demo](https://media.giphy.com/media/24G0qw2DFYwFJo3iR9/source.gif)
##### Circle mode
![Circle Mode Demo](demo/CircleModeDemo.gif)

##### Drag Circle mode
![Drag Circle Mode Demo](demo/DragCircleDemo.gif)


## Usage

Expand All @@ -15,7 +20,12 @@ npm install mapbox-gl-draw-circle
```

```
import { CircleMode, DirectMode, SimpleSelectMode } from 'mapbox-gl-draw-circle';
import {
CircleMode,
DragCircleMode,
DirectMode,
SimpleSelectMode
} from 'mapbox-gl-draw-circle';
// userProperties has to be enabled
Expand All @@ -24,7 +34,8 @@ const draw = new MapboxDraw({
userProperties: true,
modes: {
...MapboxDraw.modes,
draw_circle: CircleMode,
draw_circle : CircleMode,
drag_circle : DragCircleMode,
direct_select: DirectMode,
simple_select: SimpleSelectMode
}
Expand Down Expand Up @@ -62,3 +73,10 @@ Sample feature object returned in `draw.create` event
}
}
```

## Changelog

### v1.1.0

* Added a new DragCircle mode.
* Fixed issue (#5), where the polygon mode was not working when used along with CircleMode.
249 changes: 249 additions & 0 deletions __tests__/modes/DragCircleMode.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
jest.mock('@mapbox/mapbox-gl-draw/src/lib/double_click_zoom', () => ({
enable: jest.fn(),
disable: jest.fn()
}));

jest.mock('@turf/circle', () => ({
default: jest.fn()
}));

jest.mock('@turf/distance', () => ({
default: jest.fn()
}));

jest.mock('../../lib/utils/drag_pan', () => ({
enable: jest.fn(),
disable: jest.fn()
}));

let DragCircleMode = require('../../lib/modes/DragCircleMode');
const mockFeature = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": []
}
};
const doubleClickZoom = require('@mapbox/mapbox-gl-draw/src/lib/double_click_zoom');
const Constants = require('@mapbox/mapbox-gl-draw/src/constants');
const circle = require('@turf/circle');
const dragPan = require('../../lib/utils/drag_pan');
const distance = require('@turf/distance');

describe('DragCircleMode', function () {


beforeEach(() => {
DragCircleMode = {
...DragCircleMode,
addFeature: jest.fn(),
newFeature: jest.fn(),
clearSelectedFeatures: jest.fn(),
updateUIClasses: jest.fn(),
activateUIButton: jest.fn(),
setActionableState: jest.fn(),
changeMode: jest.fn()
}
});

afterEach(() => {
DragCircleMode.changeMode.mockClear();
});

it('should setup state with a polygon', () => {
DragCircleMode.newFeature.mockReturnValue(mockFeature);
expect(DragCircleMode.onSetup({})).toEqual({
polygon: mockFeature,
currentVertexPosition: 0
});
expect(DragCircleMode.addFeature).toHaveBeenCalledWith(mockFeature);
});

it('should clear selected features on setup', () => {
DragCircleMode.onSetup({});
expect(DragCircleMode.clearSelectedFeatures).toHaveBeenCalled();
});

it('should disable double click zoom on setup', () => {
DragCircleMode.onSetup({});
expect(doubleClickZoom.disable).toHaveBeenCalled();
});

it('should disable dragPan on setup', function () {
DragCircleMode.onSetup({});
expect(dragPan.disable).toHaveBeenCalled();
});

it('should update the center when onMouseDown is fired', function () {
const state = {
polygon: {
properties: {
center: []
}
}
};

const e = {
lngLat: {
lat: 1,
lng: 2
}
};
DragCircleMode.onMouseDown(state, e);
expect(state).toEqual({
polygon: {
properties: {
center: [2, 1]
}
}
})
});

it('should update the center when onTouchStart is fired', function () {
const state = {
polygon: {
properties: {
center: []
}
}
};

const e = {
lngLat: {
lat: 1,
lng: 2
}
};
DragCircleMode.onTouchStart(state, e);
expect(state).toEqual({
polygon: {
properties: {
center: [2, 1]
}
}
})
});

it('should discard the circle if its a click event', function () {
const state = {
polygon: {
properties: {
center: [2, 1]
}
}
};
DragCircleMode.onClick(state, {});
expect(state).toEqual({
polygon: {
properties: {
center: []
}
}
})
});

it('should discard the circle if its a tap event', function () {
const state = {
polygon: {
properties: {
center: [2, 1]
}
}
};
DragCircleMode.onTap(state, {});
expect(state).toEqual({
polygon: {
properties: {
center: []
}
}
})
});

it('should finish drawing if onMouseUp is fired', function () {
const state = {
polygon: {
id: 'test-id',
}
};
DragCircleMode.onMouseUp(state, {});
expect(dragPan.disable).toHaveBeenCalled();
expect(DragCircleMode.changeMode).toHaveBeenCalledWith(Constants.modes.SIMPLE_SELECT,
{featureIds: ['test-id']})
});

it('should finish drawing if onTouchEnd is fired', function () {
const state = {
polygon: {
id: 'test-id',
}
};
DragCircleMode.onTouchEnd(state, {});
expect(dragPan.disable).toHaveBeenCalled();
expect(DragCircleMode.changeMode).toHaveBeenCalledWith(Constants.modes.SIMPLE_SELECT,
{featureIds: ['test-id']})
});

it('should should set active state and display features', function () {
const state = {
polygon: {
id: 'test-id'
}
};

const geojson = {
properties: {
id: 'test-id'
}
};

const display = jest.fn();

DragCircleMode.toDisplayFeatures(state, geojson, display);
expect(geojson.properties.active).toEqual(Constants.activeStates.ACTIVE);
expect(display).toHaveBeenCalledWith(geojson);
});

it('should adjust the geometry when onDrag is fired', function () {
distance.default.mockReturnValue(2);
circle.default.mockReturnValue({
geometry: {
coordinates: [12, 2]
}
});
const state = {
polygon: {
properties: {
center: [1, 2],
radiusInKm: 1
},
incomingCoords: jest.fn()
}
};
DragCircleMode.onDrag(state, { lngLat: { lat: 1, lng: 2}});
expect(state.polygon.incomingCoords).toHaveBeenCalledWith([12, 2])
expect(state.polygon.properties.radiusInKm).toEqual(2);
});

it('should adjust the geometry when onMouseMove is fired', function () {
distance.default.mockReturnValue(2);
circle.default.mockReturnValue({
geometry: {
coordinates: [12, 2]
}
});
const state = {
polygon: {
properties: {
center: [1, 2],
radiusInKm: 1
},
incomingCoords: jest.fn()
}
};
DragCircleMode.onMouseMove(state, { lngLat: { lat: 1, lng: 2}});
expect(state.polygon.incomingCoords).toHaveBeenCalledWith([12, 2])
expect(state.polygon.properties.radiusInKm).toEqual(2);
});
});
Binary file added demo/CircleModeDemo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/DragCircleDemo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const CircleMode = require('./lib/modes/CircleMode');
export const DragCircleMode = require('./lib/modes/DragCircleMode');
export const DirectMode = require('./lib/modes/DirectModeOverride');
export const SimpleSelectMode = require('./lib/modes/SimpleSelectModeOverride');
export const SimpleSelectMode = require('./lib/modes/SimpleSelectModeOverride');
2 changes: 1 addition & 1 deletion lib/modes/CircleMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const Constants = require('@mapbox/mapbox-gl-draw/src/constants');
const doubleClickZoom = require('@mapbox/mapbox-gl-draw/src/lib/double_click_zoom');
const circle = require('@turf/circle').default;

const CircleMode = MapboxDraw.modes.draw_polygon;
const CircleMode = {...MapboxDraw.modes.draw_polygon};
const DEFAULT_RADIUS_IN_KM = 2;

CircleMode.onSetup = function(opts) {
Expand Down
Loading

0 comments on commit c12944f

Please sign in to comment.