If you prefer to build a signature pad in React.js without using an external library, you can implement it using HTML5 canvas and React’s state management. Here’s an example of how you can achieve this.
Table of contents
Open Table of contents
Set up a new React.js project
- Install Node.js if you haven’t already.
- Open a terminal and run the following command to create a new React.js project:
npx create-react-app signature-pad
- Move into the project directory:
cd signature-pad
Implement the signature pad component
- Open the src/App.js file in a code editor and replace its contents with the following code:
import React, { useState, useRef } from "react";
const App = () => {
const [isDrawing, setIsDrawing] = useState(false);
const canvasRef = useRef(null);
const contextRef = useRef(null);
const startDrawing = ({ nativeEvent }) => {
const { offsetX, offsetY } = nativeEvent;
setIsDrawing(true);
contextRef.current.beginPath();
contextRef.current.moveTo(offsetX, offsetY);
};
const finishDrawing = () => {
setIsDrawing(false);
};
const draw = ({ nativeEvent }) => {
if (!isDrawing) return;
const { offsetX, offsetY } = nativeEvent;
contextRef.current.lineTo(offsetX, offsetY);
contextRef.current.stroke();
};
const clearCanvas = () => {
contextRef.current.clearRect(
0,
0,
canvasRef.current.width,
canvasRef.current.height
);
};
const saveSignature = () => {
const imageDataURL = canvasRef.current.toDataURL();
// Do something with the imageDataURL (e.g., save it, send it to the server, etc.)
console.log(imageDataURL);
};
// Initialize the canvas context
React.useEffect(() => {
const canvas = canvasRef.current;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
const context = canvas.getContext("2d");
context.scale(1, 1);
context.lineCap = "round";
context.lineWidth = 2;
contextRef.current = context;
}, []);
return (
<div>
<canvas
ref={canvasRef}
onMouseDown={startDrawing}
onMouseUp={finishDrawing}
onMouseMove={draw}
style={{ border: "1px solid black" }}
/>
<div>
<button onClick={clearCanvas}>Clear</button>
<button onClick={saveSignature}>Save</button>
</div>
</div>
);
};
export default App;
Run the application
- Save the changes and close the file.
- In the terminal, run the following command to start the development server:
npm start
- Open your browser and visit
http://localhost:3000
to see the signature pad in action.
In this implementation, we use the useState hook to manage the state of the drawing process. The isDrawing state determines whether the user is currently drawing on the canvas. The canvasRef and contextRef references allow us to access the canvas element and its 2D context.
The event handlers, startDrawing, finishDrawing, and draw, handle the mouse events on the canvas. When the user clicks down, we begin a new path using beginPath and move the cursor to the clicked position. When the user releases the mouse button, we end the drawing process. The draw function is called continuously while the mouse is moved, creating a smooth drawing effect by connecting the previous and current positions with lines.
The clearCanvas function clears the canvas by using clearRect on the canvas context, effectively erasing any