Drawing in React Native with React Native SVG: Tutorial for Beginners

Drawing in a React Native application can be useful for cases where you want to take signatures, draw, or create collaborative experiences in your React Native Expo Apps. Thankfully it can easily be done with the use of the react-native-svg library. You may be wondering what is SVG?

SVG stands for Scalable Vector Graphics. It is a widely-used XML-based file format for describing two-dimensional vector graphics. Unlike raster graphics (e.g., JPEG or PNG images), which are composed of pixels and can lose quality when scaled, SVG graphics are based on mathematical equations that define shapes and paths, allowing them to be scaled to any size without losing quality.

SVG graphics are highly versatile and commonly used for web graphics, data visualization, logos, icons, and other scalable graphics.

React Native SVG is a library that enables you to use SVG files and render vector graphics in your React Native applications. It allows you to incorporate SVG graphics into your mobile app UI, just like any other React Native component. The library bridges the gap between React Native's native components and SVG elements, making it possible to display and manipulate scalable vector graphics within the app.

React Native SVG provides a set of components that correspond to SVG elements, such as <Svg>, <Circle>, <Rect>, <Path>, etc. In this tutorial, we will be showing how to use the Path component but in reality, once you learn how to do this you should be easily able to modify the code to your liking. The example we will create in this tutorial will look as follows.

Before we get started, be sure to subscribe and support the channel if you have not!

Subscribe:

Youtube

Support:

https://www.buymeacoffee.com/mmshilleh

Step 1-) Create an Expo Application

To do this, you need to have an expo as a prerequisite and run “expo init”.

Step 2-) NPM Install react-native-svg

This is the only library you will need to run the code. npm i react-native-svg

STEP 3-) Code Walkthrough

The code for the component is as follows

 

import React, { useState } from 'react';
import { View, StyleSheet, Dimensions, TouchableOpacity, Text } from 'react-native';
import { Svg, Path } from 'react-native-svg';

const { height, width } = Dimensions.get('window');

export default () => {
  const [paths, setPaths] = useState([]);
  const [currentPath, setCurrentPath] = useState([]);
  const [isClearButtonClicked, setClearButtonClicked] = useState(false);

  const onTouchEnd = () => {
    paths.push(currentPath);
    setCurrentPath([]);
    setClearButtonClicked(false);
  };

  const onTouchMove = (event) => {
    const newPath = [...currentPath];
    const locationX = event.nativeEvent.locationX;
    const locationY = event.nativeEvent.locationY;
    const newPoint = `${newPath.length === 0 ? 'M' : ''}${locationX.toFixed(0)},${locationY.toFixed(0)} `;
    newPath.push(newPoint);
    setCurrentPath(newPath);
  };

  const handleClearButtonClick = () => {
    setPaths([]);
    setCurrentPath([]);
    setClearButtonClicked(true);
  };

  return (
    <View style={styles.container}>
      <View style={styles.svgContainer} onTouchMove={onTouchMove} onTouchEnd={onTouchEnd}>
        <Svg height={height * 0.7} width={width}>
          <Path
            d={paths.join('')}
            stroke={isClearButtonClicked ? 'transparent' : 'red'}
            fill={'transparent'}
            strokeWidth={3}
            strokeLinejoin={'round'}
            strokeLinecap={'round'}
          />
          {paths.length > 0 &&
            paths.map((item, index) => (
              <Path
                key={`path-${index}`}
                d={currentPath.join('')}
                stroke={isClearButtonClicked ? 'transparent' : 'red'}
                fill={'transparent'}
                strokeWidth={2}
                strokeLinejoin={'round'}
                strokeLinecap={'round'}
              />
            ))}
        </Svg>
      </View>
      <TouchableOpacity style={styles.clearButton} onPress={handleClearButtonClick}>
        <Text style={styles.clearButtonText}>Clear</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  svgContainer: {
    height: height * 0.7,
    width,
    borderColor: 'black',
    backgroundColor: 'white',
    borderWidth: 1,
  },
  clearButton: {
    marginTop: 10,
    backgroundColor: 'black',
    paddingVertical: 10,
    paddingHorizontal: 20,
    borderRadius: 5,
  },
  clearButtonText: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

Code Breakdown:

Import Statements:

  • The code imports required modules from react, react-native, and react-native-svg.
  • These modules are needed to create the drawing canvas and handle touch events.
  • Dimensions:
    • The Dimensions object is used to get the height and width of the device's window. You do not necessarily need this but it helps us size our drawing canvas easily.
  • State Variables:
    • The code defines three state variables using the useState hook: paths, currentPath, and isClearButtonClicked.
    • paths: An array that stores all the completed drawing paths as strings. You will need to record these so that you can draw more than one line/path.
    • currentPath: An array that stores the current drawing path as it's being drawn, which eventually becomes added to the paths variable.
    • isClearButtonClicked: A boolean flag to track whether the "Clear" button has been clicked.
  • onTouchEnd() Function:
    • This function is called when the touch event ends on the drawing canvas.
    • It pushes the currentPath (the completed drawing path) into the paths array.
    • It resets the currentPath to an empty array and sets isClearButtonClicked to false.
  • onTouchMove(event) Function:
    • This function is called when the user moves their finger on the drawing canvas (during touch events).
    • It calculates the locationX and locationY coordinates of the touch event.
    • It creates a new point in the currentPath array as a string in the format "Mx,y ", where x and y are the coordinates. This is how the SVG interprets coordinates and displays them connected in a smooth manner.
    • It updates the currentPath with the new point.
  • handleClearButtonClick() Function:
    • This function is called when the "Clear" button is clicked.
    • It clears the paths array and the currentPath array, effectively resetting the drawing canvas.
    • It sets isClearButtonClicked to true.
  • Return Statement:
    • The main component is returned, and it renders a View containing two elements: the drawing canvas and a "Clear" button.
  • Drawing Canvas (<Svg> and <Path>):
    • The drawing canvas is created using the <Svg> component from react-native-svg.
    • The <Svg> component sets the height to 70% of the device window height and the width to the device window width.
    • A <Path> component is used to draw the current path (currentPath) and all completed paths (paths) on the canvas. Be aware there are other types of components you can use depending on your applicaiton.
    • The color and styling of the paths are determined by the stroke and strokeWidth props, which you can adjust.
  • "Clear" Button (<TouchableOpacity>):
    • The "Clear" button is created using the <TouchableOpacity> component from react-native.
    • When clicked, it calls the handleClearButtonClick() function to reset the drawing canvas.
  • Styles:
    • The code includes some styling using the StyleSheet.create() function to define the appearance of the drawing canvas and the "Clear" button. You will probably have to style as you need be.

Overall, this code creates a simple drawing app in React Native. Users can draw on the canvas using their finger, and the drawing paths are stored and displayed using SVG <Path> components. The "Clear" button allows users to reset the canvas and start drawing again.

Conclusion

Hope you learned how to create your canvas in React Native. If you have any questions let me know. Do not forget to subscribe and support the channel above, thanks!

Create a free account to access full content.

All access to code and resources on ShillehTek.

Signup Now

Already a member? Sign In

Explore More on Our Blog

Create Tabular Product Descriptions on Your Shopify Store

Create Tabular Product Descriptions on Your Shopify Store

Enhance your Shopify store's product pages with our comprehensive guide on implementing tabular descriptions. Learn how to add a...

SSH Into Raspberry Pi with Tailscale VPN

SSH Into Raspberry Pi with Tailscale VPN

Effortlessly access and manage your Raspberry Pi from anywhere using Tailscale's secure mesh VPN.

Send Email with Lua and the ESP32

Send Email with Lua and the ESP32

In this tutorial, we delve into sending emails with the ESP32-S3 using Lua, focusing on the Xedge IDE's built-in SMTP...

How to Code with Lua on ESP32 with XEdge32

How to Code with Lua on ESP32 with XEdge32

Learn how to set up Xedge32 and start coding on the ESP32-S3 with Lua programming!

Stream Audio From Raspberry Pi to Local Computer

Stream Audio From Raspberry Pi to Local Computer

Discover the simplicity of streaming live audio directly from a USB microphone connected to your Raspberry Pi to...

SSH Raspberry Pi via Cell Phone

SSH Raspberry Pi via Cell Phone

This beginner-friendly guide will walk you through remotely controlling your Raspberry Pi using SSH through your cell phone.

Remotely Control Raspberry Pi via SSH from External Network

Remotely Control Raspberry Pi via SSH from External Network

Learn how to SSH into your Raspberry Pi from any network. This is critical in IoT since you can control...

Stream Video from Raspberry Pi Camera to YouTube Live

Stream Video from Raspberry Pi Camera to YouTube Live

Learn how to stream to YouTube from a Raspberry Pi Camera.

How to Connect BH1750 with Arduino: Measure Ambient Light

How to Connect BH1750 with Arduino: Measure Ambient Light

Learn how to measure ambient light for smart lighting control using Arduino and the BH1750 Light Intensity Module.

How to Connect MPU9250 and Raspberry Pi (Part 2 - Calibration)

How to Connect MPU9250 and Raspberry Pi (Part 2 - Calibration)

Learn how to calibrate the MPU9250 in Python with the Raspberry Pi to get more accurate acceleration and gyroscopic...

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.