Skip to content

Commit 3797642

Browse files
committed
Add Circle component for rendering circles on a map instance
1 parent 38222df commit 3797642

File tree

3 files changed

+171
-4
lines changed

3 files changed

+171
-4
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
],
2323
"files": [
2424
"es",
25+
"Circle.js",
2526
"GoogleMap.js",
2627
"index.js",
2728
"Marker.js",
@@ -36,7 +37,7 @@
3637
"module": "es/index.js",
3738
"jsnext:main": "src/index.js",
3839
"scripts": {
39-
"clean": "rm -f index.js && rm -f GoogleMap.js && rm -f Marker.js && rm -f MarkerClusterer.js && rm -fr es && rm -fr umd",
40+
"clean": "rm -f index.js && rm -f Circle.js && rm -f GoogleMap.js && rm -f Marker.js && rm -f MarkerClusterer.js && rm -fr es && rm -fr umd",
4041
"prebuild": "npm run clean",
4142
"build": "node ./tools/build.js",
4243
"watch": "babel ./src -d . --ignore __tests__,**/*.test.js --watch",

src/Circle.js

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
const CALLBACK_MAP = {
5+
'center_changed': 'onCenterChanged',
6+
'click': 'onClick',
7+
'dblclick': 'onDoubleClick',
8+
'drag': 'onDrag',
9+
'dragend': 'onDragEnd',
10+
'dragstart': 'onDragStart',
11+
'mousedown': 'onMouseDown',
12+
'mousemove': 'onMouseMove',
13+
'mouseout': 'onMouseOut',
14+
'mouseover': 'onMouseOver',
15+
'mouseup': 'onMouseUp',
16+
'radius_changed': 'onRadiusChanged',
17+
'rightclick': 'onRightClick',
18+
'visible_changed': 'onVisibleChanged',
19+
'zindex_changed': 'onZIndexChanged',
20+
};
21+
22+
export const defaultOptions = {
23+
fillColor: '#1774ff',
24+
fillOpacity: 0.2,
25+
strokeColor: '#1774ff',
26+
strokeWeight: 2,
27+
};
28+
29+
class Circle extends Component {
30+
componentDidMount() {
31+
if (this.props.map) {
32+
this.renderCircle(this.props);
33+
}
34+
}
35+
36+
componentDidUpdate(prevProps) {
37+
const {
38+
map,
39+
center,
40+
radius,
41+
options,
42+
} = this.props;
43+
44+
let renderCircle = false;
45+
46+
if (map !== prevProps.map) {
47+
renderCircle = true;
48+
}
49+
50+
if (!Object.is(center, prevProps.center)) {
51+
renderCircle = true;
52+
}
53+
54+
if (radius !== prevProps.radius) {
55+
renderCircle = true;
56+
}
57+
58+
if (!Object.is(options, prevProps.options)) {
59+
renderCircle = true;
60+
}
61+
62+
if (renderCircle) {
63+
this.renderCircle(this.props);
64+
}
65+
}
66+
67+
componentWillUnmount() {
68+
if (!this.circle) {
69+
return;
70+
}
71+
72+
google.maps.event.clearInstanceListeners(this.circle);
73+
this.circle.setMap(null);
74+
}
75+
76+
onCircleCallback(callback, event) {
77+
this.props[callback](this.marker, event);
78+
}
79+
80+
renderCircle(props) {
81+
const {
82+
map,
83+
options,
84+
center,
85+
radius,
86+
} = props;
87+
88+
if (!map) {
89+
return;
90+
}
91+
92+
if (!this.circle) {
93+
this.circle = new google.maps.Circle({
94+
...Object.assign({}, defaultOptions, options),
95+
map,
96+
center,
97+
radius,
98+
});
99+
100+
Object.keys(CALLBACK_MAP).forEach(key => {
101+
google.maps.event.addListener(
102+
this.circle,
103+
key,
104+
this.onCircleCallback.bind(this, CALLBACK_MAP[key])
105+
);
106+
});
107+
return;
108+
}
109+
110+
this.circle.setOptions({
111+
...Object.assign({}, defaultOptions, options),
112+
map,
113+
center,
114+
radius,
115+
});
116+
}
117+
118+
render() {
119+
return null;
120+
}
121+
}
122+
123+
Circle.propTypes = {
124+
map: PropTypes.object,
125+
center: PropTypes.object.isRequired,
126+
radius: PropTypes.number,
127+
options: PropTypes.object,
128+
onCenterChanged: PropTypes.func,
129+
onClick: PropTypes.func,
130+
onDoubleClick: PropTypes.func,
131+
onDrag: PropTypes.func,
132+
onDragEnd: PropTypes.func,
133+
onDragStart: PropTypes.func,
134+
onMouseDown: PropTypes.func,
135+
onMouseMove: PropTypes.func,
136+
onMouseOut: PropTypes.func,
137+
onMouseOver: PropTypes.func,
138+
onMouseUp: PropTypes.func,
139+
onRadiusChanged: PropTypes.func,
140+
onRightClick: PropTypes.func,
141+
onVisibleChange: PropTypes.func,
142+
onZIndexChange: PropTypes.func,
143+
};
144+
145+
Circle.defaultProps = {
146+
options: defaultOptions,
147+
radius: 1000,
148+
onCenterChanged: (circle) => {},
149+
onClick: (circle) => {},
150+
onDoubleClick: (circle) => {},
151+
onDrag: (circle) => {},
152+
onDragEnd: (circle) => {},
153+
onDragStart: (circle) => {},
154+
onMouseDown: (circle) => {},
155+
onMouseMove: (circle) => {},
156+
onMouseOut: (circle) => {},
157+
onMouseOver: (circle) => {},
158+
onMouseUp: (circle) => {},
159+
onRadiusChanged: (circle) => {},
160+
onRightClick: (circle) => {},
161+
onVisibleChange: (circle) => {},
162+
onZIndexChange: (circle) => {},
163+
};
164+
165+
export default Circle;

src/index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
export {default as Marker} from './Marker';
2-
export {default as MarkerClusterer} from './MarkerClusterer';
3-
export {default as default} from './GoogleMap';
1+
export { default as Circle } from './Circle';
2+
export { default as Marker } from './Marker';
3+
export { default as MarkerClusterer } from './MarkerClusterer';
4+
export { default as default } from './GoogleMap';

0 commit comments

Comments
 (0)