Skip to content

Commit b96e711

Browse files
committed
created maps draw polygon
1 parent 5723b28 commit b96e711

File tree

19 files changed

+405
-322
lines changed

19 files changed

+405
-322
lines changed

.prettierrc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "all",
4+
"singleQuote": true,
5+
"printWidth": 90,
6+
"tabWidth": 4
7+
}

README.md

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,107 @@
1-
# react-native-maps-draw
1+
<div align="center">
2+
<img src="./draw.gif" height="500" title="React Native Maps Draw Polygon" alt="Accordion Animated" style="box-shadow: 0 20px 30px 3px rgba(9, 9, 16, 0.2);">
3+
</div>
4+
5+
<br>
6+
<br>
7+
8+
<h1 align="center">React Native Maps Draw (Polygon)</h1>
9+
<p align="center">Performance oriented React Native Accordion 60 FPS. A simple component of a common use case of collapsible - a visible title with a collapsible view beneath it.</p>
10+
<h6 align="center">Made with ❤️ by developer for developers</h6>
11+
12+
<br>
13+
<p align="center">
14+
<img src="http://img.shields.io/travis/badges/badgerbadgerbadger.svg?style=flat-square" alt="build"/>
15+
<img src="https://img.shields.io/github/issues/dev-event/react-native-accordion" alt="build"/>
16+
<img src="https://img.shields.io/bitbucket/pr-raw/dev-event/react-native-accordion" alt="build"/>
17+
<img src="http://img.shields.io/:license-mit-blue.svg?style=flat-square" alt="build"/>
18+
</p>
19+
20+
21+
22+
## Thanks
23+
<p>Please, click on ⭐ button.</p>
24+
25+
# Documentation & Examples
26+
27+
- [Installation](#installation)
28+
- [Motivation](#motivation)
29+
- [Usage](#usage)
30+
- [Props](#props)
31+
- [Example](#example)
32+
- [What's inside](#whats-inside)
33+
- [Contributing](#contributing)
34+
- [Author](#author)
35+
- [License](#license)
36+
37+
## Installation
38+
39+
```bash
40+
yarn add react-native-maps-draw
41+
# or
42+
npm install react-native-maps-draw
43+
```
44+
> Also, you need to install [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler) & [react-native-svg](https://github.com/react-native-community/react-native-svg), and follow theirs installation instructions.
45+
46+
## 🦥 Motivation
47+
- 💚 I love [React Native](https://reactnative.dev/)
48+
49+
50+
Big love and gratitude to all people who are working on React Native, Expo and React Native Navigation!
51+
52+
## Usage
53+
54+
For more complete example open [App.tsx](https://github.com/dev-event/react-native-accordion)
55+
56+
```tsx
57+
58+
```
59+
60+
61+
62+
63+
## Props
64+
65+
| name | description | required | type | default |
66+
| -------------------- | --------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------| -----------------|
67+
| `points` | An array of x, y coordinates for the drawing of the polygon. | YES | [`TouchPoint[]`](https://github.com/dev-event/react-native-maps-draw/blob/features/draw/src/types/index.ts) | [] |
68+
| `unitDistance` | Distance unit | NO | [`TouchPoint[]`](https://github.com/dev-event/react-native-maps-draw/blob/features/draw/src/maps/types.d.ts)| 'm' |
69+
| `colorLine` | Drawing line color | NO | string | '#791679' |
70+
| `widthLine` | Drawing line width | NO | number | 3 |
71+
| `onEndDraw` | Callback is called after drawing is complete | NO | (item: IDrawResult) => void | |
72+
| `isDrawMode` | Draw mode enabled / disabled | NO | YES | boolean | false |
73+
| `renderPath` | Custom canvas for drawing | NO | (path: string) => JSX.Element | |
74+
| `onStartDraw` | Callback is called when drawing starts | NO | () => void | |
75+
| `createdPolygon` | Polygon rendering modifier | YES | boolean | true |
76+
| `onChangePoints` | Callback returns x, y touches | YES | (points: TouchPoint[]) => void | |
77+
| `fillColorCanvas` | Canvas background | NO | string | 'rgba(0,0,0,0.0)'|
78+
| `backgroundCanvas` | The background of the View element overlapping the map (zIndex: 1) | NO | string | rgba(0,0,0,0.10) |
79+
80+
## 🎉 Example
81+
82+
Checkout the example [here](https://github.com/dev-event/react-native-accordion).
83+
84+
85+
## 📖 What's inside
86+
- [React Native Maps](https://github.com/wix/react-native-navigation) - is a component system for maps that ships with platform-native code that needs to be compiled together with React Native.
87+
- [React Native Svg](https://github.com/react-native-svg/react-native-svg) - provides SVG support to React Native on iOS and Android, and a compatibility layer for the web.
88+
89+
90+
## ✌️ Contributing
91+
92+
Pull requests are always welcome! Feel free to open a new GitHub issue for any changes that can be made.
93+
94+
## Author
95+
96+
Reach out to me at one of the following places!
97+
98+
- E-mail <a href="#" target="_blank">effectwaater@gmail.com</a>
99+
- Medium at <a href="https://medium.com/@effectwaaters" target="_blank">https://medium.com/@effectwaaters </a>
100+
- Instagram at <a href="https://www.instagram.com/dev_event/" target="_blank">https://www.instagram.com/dev_event/ </a>
101+
102+
103+
## License
104+
105+
[![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://badges.mit-license.org)
106+
107+
- **[MIT license](http://opensource.org/licenses/mit-license.php)**

draw.gif

6.05 MB
Loading

example/src/App.tsx

Lines changed: 58 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,38 @@
11
import React, { useState, useCallback, useRef } from 'react';
2-
import {
3-
StyleSheet,
4-
View,
5-
TouchableOpacity,
6-
Text,
7-
Image,
8-
Platform,
9-
} from 'react-native';
10-
import MapView, { ILocationProps } from '../../src';
2+
import { StyleSheet, View, TouchableOpacity, Platform, Text } from 'react-native';
3+
import MapView, { ILocationProps, IDrawResult, TouchPoint, Marker } from '../../src';
114
import { MarkerLocation } from './assets';
12-
import { Marker, Polygon } from 'react-native-maps';
13-
import { TouchPoint } from '../../src/types';
5+
import AnimatedPolygon from './components/polygon';
146

157
export default function App() {
168
const mapRef = useRef<MapView>(null);
179

1810
const initialPolygon = useRef({
1911
polygons: [],
12+
distance: 0,
2013
lastLatLng: undefined,
2114
initialLatLng: undefined,
2215
centerLatLng: undefined,
2316
});
2417

18+
const [modePolygon, setPolygonCreated] = useState<boolean>(false);
19+
2520
const [isActiveDraw, setDrawMode] = useState<boolean>(false);
2621
const [isReady, setIsReady] = useState<boolean>(false);
2722
const [points, setPoints] = useState<TouchPoint[]>([]);
2823

29-
const [polygon, setPolygon] = useState<{
30-
polygons: ILocationProps[];
31-
lastLatLng: ILocationProps;
32-
initialLatLng: ILocationProps;
33-
centerLatLng: ILocationProps;
34-
}>(initialPolygon.current);
24+
const [polygon, setPolygon] = useState<IDrawResult>(initialPolygon.current);
3525

36-
const handleMapReady = useCallback(
37-
() => mapRef.current && setIsReady(true),
38-
[]
39-
);
26+
const handleMapReady = useCallback(() => mapRef.current && setIsReady(true), []);
4027

4128
const handleRemovePolygon = useCallback(() => {
4229
setPolygon(initialPolygon.current);
30+
setPolygonCreated(false);
4331
}, []);
4432

4533
const handleClear = useCallback(() => {
4634
setPolygon(initialPolygon.current);
35+
setPolygonCreated(false);
4736
setPoints([]);
4837
}, []);
4938

@@ -55,8 +44,11 @@ export default function App() {
5544
setDrawMode((prevMode) => !prevMode);
5645
}, [handleClear, isActiveDraw]);
5746

58-
const handleCanvasDraw = useCallback((locations) => {
59-
zoomCenterPolygon(locations.centerLatLng).then(() => setPolygon(locations));
47+
const handleCanvasEndDraw = useCallback((locations) => {
48+
zoomCenterPolygon(locations.centerLatLng).then(() => {
49+
setPolygon(locations);
50+
setPolygonCreated(true);
51+
});
6052
setDrawMode((prevMode) => !prevMode);
6153
}, []);
6254

@@ -66,11 +58,11 @@ export default function App() {
6658
if (Platform.OS === 'ios') {
6759
mapRef.current.animateCamera({
6860
center: center,
69-
altitude: camera.altitude / 1.3,
61+
// altitude: camera.altitude / 2,
7062
});
7163
}
7264
if (Platform.OS === 'android') {
73-
mapRef.current.animateCamera({ center, zoom: camera.zoom + 1 });
65+
// mapRef.current.animateCamera({ center, zoom: camera.zoom + 1 });
7466
}
7567
};
7668

@@ -79,7 +71,7 @@ export default function App() {
7971

8072
const camera = await mapRef.current.getCamera();
8173
if (Platform.OS === 'ios') {
82-
mapRef.current.animateCamera({ altitude: camera.altitude * 2 });
74+
mapRef.current.animateCamera({ altitude: camera.altitude * 1 });
8375
}
8476

8577
if (Platform.OS === 'android') {
@@ -94,82 +86,57 @@ export default function App() {
9486
);
9587

9688
const handlePolygon = useCallback(
97-
(item, index) => (
98-
<Polygon
99-
key={index}
100-
coordinates={polygon.polygons}
101-
fillColor="rgba(0, 0, 0, 0.00)"
102-
strokeColor="rgba(0, 0, 0, 0.00)"
103-
strokeWidth={0}
104-
/>
105-
),
89+
(item, index) => <AnimatedPolygon key={index} coordinates={polygon.polygons} />,
10690
[polygon.polygons]
10791
);
10892

109-
const handleBlockText = useCallback(() => {
110-
return (
111-
<>
112-
<View style={styles.header}>
113-
<Text style={styles.title}>Draw mode preview</Text>
114-
</View>
115-
116-
<View style={styles.content}>
117-
<Text style={styles.title}>What is Lorem Ipsum?</Text>
118-
<Text style={styles.description} adjustsFontSizeToFit={true}>
119-
Lorem Ipsum has been the industry's standard dummy text ever since
120-
the 1500s, when an unknown printer took a galley of type and
121-
scrambled it to make a type specimen book.
122-
</Text>
123-
<View style={[styles.row, { justifyContent: 'space-between' }]}>
124-
<View style={styles.row}>
125-
<Image
126-
source={require('../src/assets/pencil.png')}
127-
resizeMode={'contain'}
128-
style={{ tintColor: 'white' }}
129-
/>
130-
<Text style={styles.name}>28 miles</Text>
131-
</View>
132-
133-
<View style={styles.row}>
134-
<Image
135-
source={require('../src/assets/pencil.png')}
136-
resizeMode={'contain'}
137-
style={{ tintColor: 'white' }}
138-
/>
139-
<Text style={styles.name}>4.5 h</Text>
140-
</View>
141-
142-
<View style={styles.row}>
143-
<Image
144-
source={require('../src/assets/pencil.png')}
145-
resizeMode={'contain'}
146-
style={{ tintColor: 'white' }}
147-
/>
148-
<Text style={styles.name}>hard</Text>
149-
</View>
150-
</View>
151-
</View>
152-
</>
153-
);
93+
const onChangePoints = useCallback((value) => {
94+
setPoints(value);
15495
}, []);
15596

97+
//
98+
// const hasOverlay = useMemo(() => {
99+
// if (renderOverlayPolygon === null) {
100+
// return null;
101+
// }
102+
//
103+
// return renderOverlayPolygon !== undefined
104+
// ? renderOverlayPolygon(path)
105+
// : !!path && (
106+
// <OverlayPolygon
107+
// {...{
108+
// path,
109+
// fillOverlay,
110+
// widthOverlayLine,
111+
// colorWidthOverlayLine,
112+
// backgroundOverlayPolygon,
113+
// }}
114+
// />
115+
// );
116+
// }, [
117+
// path,
118+
// fillOverlay,
119+
// widthOverlayLine,
120+
// renderOverlayPolygon,
121+
// colorWidthOverlayLine,
122+
// backgroundOverlayPolygon,
123+
// ]);
156124
return (
157125
<View style={styles.container}>
158126
<MapView
159127
ref={mapRef}
160128
style={{ flex: 1 }}
161129
points={points}
162-
colorLine={'tomato'}
163-
onEndDraw={handleCanvasDraw}
130+
widthLine={3}
131+
onEndDraw={handleCanvasEndDraw}
164132
isDrawMode={isActiveDraw}
165133
onMapReady={handleMapReady}
166134
onStartDraw={handleClear}
167-
onChangePoints={setPoints}
168-
widthLine={3}
169-
backgroundCanvas={'rgba(25, 0, 64, 0.62)'}
170-
renderContentGesture={handleBlockText}
135+
createdPolygon={modePolygon}
136+
onChangePoints={onChangePoints}
137+
backgroundCanvas={'rgba(0, 0, 0, 0.0)'}
171138
>
172-
{isReady && polygon.polygons && polygon.polygons.length > 0 && (
139+
{isReady && modePolygon && polygon.polygons && polygon.polygons.length > 0 && (
173140
<>
174141
{hasMarkerClose}
175142
{polygon.polygons.map(handlePolygon)}
@@ -179,17 +146,9 @@ export default function App() {
179146

180147
<TouchableOpacity style={styles.button} onPress={handleIsDraw}>
181148
{isActiveDraw ? (
182-
<Image
183-
source={require('../src/assets/close.png')}
184-
resizeMode={'contain'}
185-
style={{ tintColor: 'white' }}
186-
/>
149+
<Text style={styles.title}>ON</Text>
187150
) : (
188-
<Image
189-
source={require('../src/assets/pencil.png')}
190-
resizeMode={'contain'}
191-
style={{ tintColor: 'white' }}
192-
/>
151+
<Text style={styles.title}>OFF</Text>
193152
)}
194153
</TouchableOpacity>
195154
</View>
@@ -204,39 +163,13 @@ const styles = StyleSheet.create({
204163
top: '10%',
205164
right: '10%',
206165
position: 'absolute',
166+
backgroundColor: 'tomato',
207167
padding: 16,
208168
zIndex: 4,
209169
borderRadius: 18,
210170
},
211-
content: {
212-
paddingHorizontal: 18,
213-
position: 'absolute',
214-
bottom: 70,
215-
},
216-
header: {
217-
paddingHorizontal: 18,
218-
position: 'absolute',
219-
top: 70,
220-
width: '100%',
221-
alignItems: 'center',
222-
},
223171
title: {
224172
color: '#FFFFFF',
225-
fontSize: 20,
226-
marginBottom: 14,
227-
},
228-
description: {
229-
color: '#DDDDDD',
230-
fontSize: 14,
231-
marginBottom: 28,
232-
},
233-
name: {
234-
color: '#DDDDDD',
235-
fontSize: 14,
236-
},
237-
row: {
238-
flexDirection: 'row',
239-
justifyContent: 'space-between',
240-
alignItems: 'center',
173+
fontSize: 12,
241174
},
242175
});

example/src/assets/close.png

-282 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)