How to create a Paint App in ReactJS ?
In this article, we will be building a simple paint application that lets you draw just like in MS-Paint. Through this article, we will learn how to implement and work with canvas in React.js.
Our app contains two sections, one for drawing and the other is a menu where the user can customize the brush color, width, and opacity.
Prerequisites: The pre-requisites for this project are:
Creating a React application:
- Step 1: Create a react application by typing the following command in the terminal:
npx create-react-app paint-app
- Step 2: Now, go to the project folder i.e paint-app by running the following command:
cd paint-app
Project Structure: It will look like this:
Filename: App.js In this file we will implement the canvas and work with it. Here we create three functions: startDrawing(), endDrawing() and draw(). The main idea is that whenever the mouse button is down, we execute the startDrawing function so that the cursor knows the x and y coordinate (starting coordinates) and we toggle the isDrawing state to true. Now whenever the user moves the mouse, we execute the draw function which will draw a stroke in the current x and y coordinate. If the user lifts the mouse button up we execute the endDrawing function which will close the stroke path and toggle the isDrawing state to false simultaneously. Now write down the following code in the App.js component.
Javascript
import { useEffect, useRef, useState } from "react" ; import Menu from "./components/Menu" ; import "./App.css" ; function App() { const canvasRef = useRef( null ); const ctxRef = useRef( null ); const [isDrawing, setIsDrawing] = useState( false ); const [lineWidth, setLineWidth] = useState(5); const [lineColor, setLineColor] = useState( "black" ); const [lineOpacity, setLineOpacity] = useState(0.1); // Initialization when the component // mounts for the first time useEffect(() => { const canvas = canvasRef.current; const ctx = canvas.getContext( "2d" ); ctx.lineCap = "round" ; ctx.lineJoin = "round" ; ctx.globalAlpha = lineOpacity; ctx.strokeStyle = lineColor; ctx.lineWidth = lineWidth; ctxRef.current = ctx; }, [lineColor, lineOpacity, lineWidth]); // Function for starting the drawing const startDrawing = (e) => { ctxRef.current.beginPath(); ctxRef.current.moveTo( e.nativeEvent.offsetX, e.nativeEvent.offsetY ); setIsDrawing( true ); }; // Function for ending the drawing const endDrawing = () => { ctxRef.current.closePath(); setIsDrawing( false ); }; const draw = (e) => { if (!isDrawing) { return ; } ctxRef.current.lineTo( e.nativeEvent.offsetX, e.nativeEvent.offsetY ); ctxRef.current.stroke(); }; return ( <div className= "App" > <h1>Paint App</h1> <div className= "draw-area" > <Menu setLineColor={setLineColor} setLineWidth={setLineWidth} setLineOpacity={setLineOpacity} /> <canvas onMouseDown={startDrawing} onMouseUp={endDrawing} onMouseMove={draw} ref={canvasRef} width={`1280px`} height={`720px`} /> </div> </div> ); } export default App; |
Filename: Menu.js Let’s create a menu bar where users can customize the brush color, size, and opacity. First, create a folder name components under the src folder. Then create a file name Menu.jsx inside the components folder. We will import this custom component inside the App.js file. Now write down the following code in Menu.jsx
Javascript
import React from "react" ; import "../App.css" ; const Menu = ({ setLineColor, setLineWidth, setLineOpacity }) => { return ( <div className= "Menu" > <label>Brush Color </label> <input type= "color" onChange={(e) => { setLineColor(e.target.value); }} /> <label>Brush Width </label> <input type= "range" min= "3" max= "20" onChange={(e) => { setLineWidth(e.target.value); }} /> <label>Brush Opacity</label> <input type= "range" min= "1" max= "100" onChange={(e) => { setLineOpacity(e.target.value / 100); }} /> </div> ); }; export default Menu; |
Filename: App.css Let’s style our paint app.
CSS
@import url ( .App { width : 100% ; height : 100 vh; display : flex; flex- direction : column; justify- content : flex-start; align-items: center ; background-image : linear-gradient( 120 deg, #fdfbfb 0% , #ebedee 100% ); } h 1 { font-family : 'Lobster' , cursive ; font-size : 50px ; color : #4644f0 ; } .draw-area { width : 1280px ; height : 720px ; border : 2px solid #808080 ; position : relative ; background-color : white ; } .Menu { width : 650px ; height : 50px ; display : flex; justify- content : space-evenly; border-radius: 5px ; align-items: center ; background-color : #a3a3a3 2d; margin : auto ; margin-top : 10px ; } |
Step to Run Application: Run the application using the following command from the root directory of the project.
npm start
Output: Now open your browser and go to http://localhost:3000/, you will see the following output:
Please Login to comment...