Skip to content

react-states/react-native-maps-draw

Β 
Β 

Repository files navigation

Accordion Animated


React Native Maps Draw (Polygon)

Interactive drawing of polygons on the map. Beta version

Made with ❀️ by developer for developers

build build build build

Thanks

Please, click on ⭐ button.

Documentation & Examples

Installation

yarn add @dev-event/react-native-maps-draw
# or
npm install @dev-event/react-native-maps-draw

Also, you need to install react-native-gesture-handler & react-native-svg, and follow theirs installation instructions.

πŸ¦₯ Motivation

Big love and gratitude to all people who are working on React Native, Expo and React Native Navigation!

Usage

For more complete example open App.tsx

import React, { useState, useCallback, useRef } from 'react';
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
import MapView, { 
  ILocationProps,
  IDrawResult, 
  TouchPoint,
  Marker
} from 'react-native-maps-draw';


const App: React.FC = () => {
  const mapRef = useRef<MapView>(null);

  const initialPolygon = useRef({
    polygons: [],
    distance: 0,
    lastLatLng: undefined,
    initialLatLng: undefined,
    centerLatLng: undefined,
  });

  const [modePolygon, setPolygonCreated] = useState<boolean>(false);

  const [isActiveDraw, setDrawMode] = useState<boolean>(false);
  const [isReady, setIsReady] = useState<boolean>(false);
  const [points, setPoints] = useState<TouchPoint[]>([]);

  const [polygon, setPolygon] = useState<IDrawResult>(initialPolygon.current);

  const handleMapReady = useCallback(() => mapRef.current && setIsReady(true), []);

  const handleRemovePolygon = useCallback(() => {
    setPolygon(initialPolygon.current);
    setPolygonCreated(false);
  }, []);

  const handleClear = useCallback(() => {
    setPolygon(initialPolygon.current);
    setPolygonCreated(false);
    setPoints([]);
  }, []);

  const handleIsDraw = useCallback(() => {
    if (!mapRef.current) return;
    setDrawMode((prevMode) => !prevMode);
  }, [handleClear, isActiveDraw]);

  const handleCanvasEndDraw = useCallback((locations) => {
    zoomCenterPolygon(locations.centerLatLng).then(() => {
      setPolygon(locations);
      setPolygonCreated(true);
    });
    setDrawMode((prevMode) => !prevMode);
  }, []);

  const zoomCenterPolygon = async (center: ILocationProps) => {
    if (!mapRef.current) return;
    const camera = await mapRef.current.getCamera();
    if (Platform.OS === 'ios') {
      mapRef.current.animateCamera({
        center: center,
      });
    }
    if (Platform.OS === 'android') {}
  };

 
  const hasMarkerClose = polygon.centerLatLng && (
    <Marker onPress={handleRemovePolygon} coordinate={polygon.centerLatLng}>
      <MarkerLocation />
    </Marker>
  );

  const handlePolygon = useCallback(
    (item, index) => <AnimatedPolygon key={index} coordinates={polygon.polygons} />,
    [polygon.polygons]
  );
  
  
  return (
    <View style={styles.container}>
      <MapView
        ref={mapRef}
        style={{ flex: 1 }}
        points={points}
        widthLine={3}
        onEndDraw={handleCanvasEndDraw}
        isDrawMode={isActiveDraw}
        onMapReady={handleMapReady}
        onStartDraw={handleClear}
        createdPolygon={modePolygon}
        onChangePoints={setPoints}
        backgroundCanvas={'rgba(0, 0, 0, 0.0)'}
      >
        {isReady && modePolygon && polygon.polygons && polygon.polygons.length > 0 && (
          <>
            {hasMarkerClose}
            {polygon.polygons.map(handlePolygon)}
          </>
        )}
      </MapView>

      <TouchableOpacity style={styles.button} onPress={handleIsDraw}>
        {isActiveDraw ? (
          <Text style={styles.title}>ON</Text>
        ) : (
          <Text style={styles.title}>OFF</Text>
        )}
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  button: {
    top: '10%',
    right: '10%',
    position: 'absolute',
    backgroundColor: 'tomato',
    padding: 16,
    zIndex: 4,
    borderRadius: 18,
  },
  title: {
    color: '#FFFFFF',
    fontSize: 12,
  },
});

Props

name description required type default
points An array of x, y coordinates for the drawing of the polygon. YES TouchPoint[] []
unitDistance Distance unit NO Units 'm'
colorLine Drawing line color NO string '#791679'
widthLine Drawing line width NO number 3
onEndDraw Callback is called after drawing is complete NO (item: IDrawResult) => void
isDrawMode Draw mode enabled / disabled NO YES boolean
renderPath Custom canvas for drawing NO (path: string) => JSX.Element
onStartDraw Callback is called when drawing starts NO () => void
createdPolygon Polygon rendering modifier YES boolean true
onChangePoints Callback returns x, y touches YES (points: TouchPoint[]) => void
fillColorCanvas Canvas background NO string 'rgba(0,0,0,0.0)'
backgroundCanvas The background of the View element overlapping the map (zIndex: 1) NO string rgba(0,0,0,0.10)

πŸŽ‰ Example

Checkout the example here.

πŸ“– What's inside

  • React Native Maps - is a component system for maps that ships with platform-native code that needs to be compiled together with React Native.
  • React Native Svg - provides SVG support to React Native on iOS and Android, and a compatibility layer for the web.

✌️ Contributing

Pull requests are always welcome! Feel free to open a new GitHub issue for any changes that can be made.

Author

Reach out to me at one of the following places!

License

License

About

Interactive drawing of polygons on the map.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 86.9%
  • JavaScript 13.1%