import React, { useRef, useState, useEffect } from 'react';
import './App.css';
const App = () => {
const canvasRef = useRef(null);
const contextRef = useRef(null);
const [isDrawing, setIsDrawing] = useState(false);
const [canvasHistory, setCanvasHistory] = useState([]);
const [historyIndex, setHistoryIndex] = useState(0);
const [tool, setTool] = useState('draw');
const [shapeStart, setShapeStart] = useState(null);
useEffect(() => {
const canvas = canvasRef.current;
canvas.width = window.innerWidth * 0.8;
canvas.height = window.innerHeight * 0.8;
canvas.style.width = ${window.innerWidth * 0.8}px;
canvas.style.height = ${window.innerHeight * 0.8}px;
const context = canvas.getContext('2d');
context.scale(1, 1);
context.lineCap = 'round';
context.strokeStyle = 'black';
context.lineWidth = 5;
contextRef.current = context;
saveCanvasState();
}, []);
const startDrawing = ({ nativeEvent }) => {
const { offsetX, offsetY } = nativeEvent;
if (tool === 'draw' || tool === 'erase') {
contextRef.current.beginPath();
contextRef.current.moveTo(offsetX, offsetY);
setIsDrawing(true);
} else if (tool === 'rect' || tool === 'circle') {
setShapeStart({ offsetX, offsetY });
setIsDrawing(true);
};
const finishDrawing = () => {
if (!isDrawing) return;
contextRef.current.closePath();
setIsDrawing(false);
saveCanvasState();
};
const draw = ({ nativeEvent }) => {
if (!isDrawing) return;
const { offsetX, offsetY } = nativeEvent;
if (tool === 'draw') {
contextRef.current.lineTo(offsetX, offsetY);
contextRef.current.stroke();
} else if (tool === 'erase') {
contextRef.current.clearRect(offsetX - 5, offsetY - 5, 10, 10);
} else if (tool === 'rect' || tool === 'circle') {
redrawCanvas();
if (tool === 'rect') {
drawRectangle(shapeStart.offsetX, shapeStart.offsetY, offsetX, offsetY);
} else if (tool === 'circle') {
drawCircle(shapeStart.offsetX, shapeStart.offsetY, offsetX, offsetY);
};
const drawRectangle = (x1, y1, x2, y2) => {
const context = contextRef.current;
const width = x2 - x1;
const height = y2 - y1;
context.strokeRect(x1, y1, width, height);
};
const drawCircle = (x1, y1, x2, y2) => {
const context = contextRef.current;
const radius = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
context.beginPath();
context.arc(x1, y1, radius, 0, Math.PI * 2);
context.stroke();
};
const saveCanvasState = () => {
const canvas = canvasRef.current;
const newState = canvas.toDataURL();
const newHistory = [...canvasHistory.slice(0, historyIndex), newState];
setCanvasHistory(newHistory);
setHistoryIndex(newHistory.length);
};
const redrawCanvas = () => {
const canvas = canvasRef.current;
const context = contextRef.current;
const currentState = canvasHistory[historyIndex - 1];
const img = new Image();
img.src = currentState;
img.onload = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);
};
};
const undo = () => {
if (historyIndex > 1) {
setHistoryIndex(historyIndex - 1);
redrawCanvas();
};
const handleToolChange = (e) => {
setTool(e.target.value);
};
return (
<div>
<div className="toolbar">
<button onClick={undo}>Undo</button>
<select onChange={handleToolChange} value={tool}>
<option value="draw">Draw</option>
<option value="erase">Erase</option>
<option value="rect">Rectangle</option>
<option value="circle">Circle</option>
</select>
</div>
<canvas
ref={canvasRef}
onMouseDown={startDrawing}
onMouseUp={finishDrawing}
onMouseMove={draw}
className="canvas"
/>
</div>
);
};
export default App;