Skip to content

Commit 5c98d25

Browse files
committed
feat: add Circle
1 parent e5f6943 commit 5c98d25

7 files changed

Lines changed: 191 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Google map react componentize project
1313
- [x] Polyline
1414
- [x] Polygon
1515
- [x] Rectangle
16-
- [ ] Circle
16+
- [x] Circle
1717
- [ ] AdvancedMarkerView
1818
- [ ] MarkerClusterer
1919
- [ ] HeatmapLayer

src/components/Circle/index.tsx

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { forwardRef, useEffect, useState } from 'react';
2+
3+
import { CircleProps } from './type';
4+
import { useApplyCircleEvent } from '../../hooks/useApplyCircleEvent';
5+
import { useApplyCircleOptions } from '../../hooks/useApplyCircleOptions';
6+
import { passRef } from '../../utils/passRef';
7+
import { useMapContext } from '../Provider/MapProvider';
8+
9+
export const Circle = forwardRef<google.maps.Circle, CircleProps>(
10+
function Circle(
11+
{
12+
center,
13+
clickable,
14+
draggable,
15+
editable,
16+
fillColor,
17+
fillOpacity,
18+
radius,
19+
strokeColor,
20+
strokeOpacity,
21+
strokePosition,
22+
strokeWeight,
23+
visible,
24+
zIndex,
25+
...events
26+
},
27+
ref,
28+
) {
29+
const map = useMapContext();
30+
31+
const [Circle, setCircle] = useState<google.maps.Circle | null>(null);
32+
33+
useEffect(() => {
34+
const Circle = new google.maps.Circle({
35+
map,
36+
center,
37+
clickable,
38+
draggable,
39+
editable,
40+
fillColor,
41+
fillOpacity,
42+
radius,
43+
strokeColor,
44+
strokeOpacity,
45+
strokePosition,
46+
strokeWeight,
47+
visible,
48+
zIndex,
49+
});
50+
51+
setCircle(Circle);
52+
passRef(ref, Circle);
53+
54+
return () => {
55+
Circle.setMap(null);
56+
};
57+
}, []);
58+
59+
useApplyCircleOptions(Circle, {
60+
center,
61+
clickable,
62+
draggable,
63+
editable,
64+
fillColor,
65+
fillOpacity,
66+
radius,
67+
strokeColor,
68+
strokeOpacity,
69+
strokePosition,
70+
strokeWeight,
71+
visible,
72+
zIndex,
73+
});
74+
useApplyCircleEvent(Circle, events);
75+
76+
return null;
77+
},
78+
);

src/components/Circle/type.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
export interface CircleEvent {
2+
onCenterChanged?: (circle: google.maps.Circle) => void;
3+
onClick?: (
4+
circle: google.maps.Circle,
5+
event: google.maps.PolyMouseEvent,
6+
) => void;
7+
onContextmenu?: (
8+
circle: google.maps.Circle,
9+
event: google.maps.PolyMouseEvent,
10+
) => void;
11+
onDblClick?: (
12+
circle: google.maps.Circle,
13+
event: google.maps.PolyMouseEvent,
14+
) => void;
15+
onDrag?: (
16+
circle: google.maps.Circle,
17+
event: google.maps.MapMouseEvent,
18+
) => void;
19+
onDragEnd?: (
20+
circle: google.maps.Circle,
21+
event: google.maps.MapMouseEvent,
22+
) => void;
23+
onDragStart?: (
24+
circle: google.maps.Circle,
25+
event: google.maps.MapMouseEvent,
26+
) => void;
27+
onMouseDown?: (
28+
circle: google.maps.Circle,
29+
event: google.maps.PolyMouseEvent,
30+
) => void;
31+
onMouseMove?: (
32+
circle: google.maps.Circle,
33+
event: google.maps.PolyMouseEvent,
34+
) => void;
35+
onMouseOut?: (
36+
circle: google.maps.Circle,
37+
event: google.maps.PolyMouseEvent,
38+
) => void;
39+
onMouseOver?: (
40+
circle: google.maps.Circle,
41+
event: google.maps.PolyMouseEvent,
42+
) => void;
43+
onMouseUp?: (
44+
circle: google.maps.Circle,
45+
event: google.maps.PolyMouseEvent,
46+
) => void;
47+
onRadiusChanged?: (
48+
circle: google.maps.Circle,
49+
event: google.maps.PolyMouseEvent,
50+
) => void;
51+
}
52+
53+
export interface CircleProps
54+
extends Partial<Omit<google.maps.CircleOptions, 'map'>>,
55+
CircleEvent {}

src/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export * from './Polygon/index';
1616
export * from './Polygon/type';
1717
export * from './Rectangle/index';
1818
export * from './Rectangle/type';
19+
export * from './Circle/index';
20+
export * from './Circle/type';
1921
export * from './Provider/MapProvider';
2022
export * from './Provider/MarkerProvider';
2123
export * from './Provider/CustomMarkerProvider';

src/hooks/useApplyCircleEvent.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { CircleEvent } from 'src/components/Circle/type';
2+
3+
import { useMvcObjectEventEffect } from './useMvcObjectEventEffect';
4+
5+
export const useApplyCircleEvent = (
6+
circle: google.maps.Circle | null,
7+
{
8+
onCenterChanged,
9+
onClick,
10+
onDblClick,
11+
onDrag,
12+
onDragEnd,
13+
onDragStart,
14+
onMouseDown,
15+
onMouseMove,
16+
onMouseOut,
17+
onMouseOver,
18+
onMouseUp,
19+
onRadiusChanged,
20+
}: CircleEvent,
21+
) => {
22+
useMvcObjectEventEffect(circle, 'center_changed', onCenterChanged);
23+
useMvcObjectEventEffect(circle, 'click', onClick);
24+
useMvcObjectEventEffect(circle, 'dblclick', onDblClick);
25+
useMvcObjectEventEffect(circle, 'drag', onDrag);
26+
useMvcObjectEventEffect(circle, 'dragend', onDragEnd);
27+
useMvcObjectEventEffect(circle, 'dragstart', onDragStart);
28+
useMvcObjectEventEffect(circle, 'mousedown', onMouseDown);
29+
useMvcObjectEventEffect(circle, 'mousemove', onMouseMove);
30+
useMvcObjectEventEffect(circle, 'mouseout', onMouseOut);
31+
useMvcObjectEventEffect(circle, 'mouseover', onMouseOver);
32+
useMvcObjectEventEffect(circle, 'mouseup', onMouseUp);
33+
useMvcObjectEventEffect(circle, 'radius_changed', onRadiusChanged);
34+
};

src/hooks/useApplyCircleOptions.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { useEffect } from 'react';
2+
3+
import { CircleEvent, CircleProps } from '../components/Circle/type';
4+
5+
export const useApplyCircleOptions = (
6+
circle: google.maps.Circle | null,
7+
{ center, ...options }: Omit<CircleProps, keyof CircleEvent>,
8+
) => {
9+
useEffect(() => {
10+
circle?.setOptions(options);
11+
}, Object.values(options));
12+
13+
useEffect(() => {
14+
circle?.setCenter(center ?? null);
15+
}, [center]);
16+
};

src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Polyline,
55
Polygon,
66
Rectangle,
7+
Circle,
78
CustomMarker,
89
InfoWindow,
910
GoogleMap,
@@ -18,6 +19,7 @@ import type {
1819
PolylineProps,
1920
PolygonProps,
2021
RectangleProps,
22+
CircleProps,
2123
CustomMarkerProps,
2224
InfoWindowProps,
2325
GoogleMapProps,
@@ -38,6 +40,7 @@ export {
3840
Polyline,
3941
Polygon,
4042
Rectangle,
43+
Circle,
4144
CustomMarker,
4245
InfoWindow,
4346
GoogleMap,
@@ -57,6 +60,7 @@ export type {
5760
PolylineProps,
5861
PolygonProps,
5962
RectangleProps,
63+
CircleProps,
6064
InfoWindowProps,
6165
CustomMarkerProps,
6266
GoogleMapProps,
@@ -76,6 +80,7 @@ export default {
7680
Polyline,
7781
Polygon,
7882
Rectangle,
83+
Circle,
7984
CustomMarker,
8085
InfoWindow,
8186
GoogleMap,

0 commit comments

Comments
 (0)