main
parent
bfc4b61b83
commit
274974db10
|
@ -1,7 +1,7 @@
|
||||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||||
import { ChromePicker } from 'react-color';
|
import { ChromePicker } from 'react-color';
|
||||||
|
|
||||||
// Update drawShape to handle pencil strokes
|
// Update drawShape to handle images
|
||||||
const drawShape = (ctx, shape) => {
|
const drawShape = (ctx, shape) => {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.strokeStyle = shape.color;
|
ctx.strokeStyle = shape.color;
|
||||||
|
@ -19,6 +19,8 @@ const drawShape = (ctx, shape) => {
|
||||||
ctx.lineTo(shape.points[i].x, shape.points[i].y);
|
ctx.lineTo(shape.points[i].x, shape.points[i].y);
|
||||||
}
|
}
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
} else if (shape.type === 'image' && shape.image) {
|
||||||
|
ctx.drawImage(shape.image, shape.x, shape.y, shape.width, shape.height);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,6 +34,7 @@ const DrawingCanvas = () => {
|
||||||
const [currentTool, setCurrentTool] = useState('pencil');
|
const [currentTool, setCurrentTool] = useState('pencil');
|
||||||
const [color, setColor] = useState('#000000');
|
const [color, setColor] = useState('#000000');
|
||||||
const [thickness, setThickness] = useState(2);
|
const [thickness, setThickness] = useState(2);
|
||||||
|
const fileInputRef = useRef(null);
|
||||||
|
|
||||||
// Resize canvas on window resize
|
// Resize canvas on window resize
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -186,6 +189,43 @@ const DrawingCanvas = () => {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [isDrawing, lastPosition, currentTool, color, thickness, shapes]);
|
}, [isDrawing, lastPosition, currentTool, color, thickness, shapes]);
|
||||||
|
|
||||||
|
// Insert Image Handler
|
||||||
|
const handleInsertImage = (e) => {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
const img = new window.Image();
|
||||||
|
img.onload = () => {
|
||||||
|
// You can set default size or let user drag to size
|
||||||
|
const x = 50, y = 50, width = img.width > 300 ? 300 : img.width, height = img.height > 300 ? 300 : img.height;
|
||||||
|
setShapes(prev => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
type: 'image',
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
image: img
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
// Save to history for undo
|
||||||
|
setHistory(prev => [...prev, deepCopyShapes([...shapes, { type: 'image', x, y, width, height, image: img }])]);
|
||||||
|
setUndoHistory([]);
|
||||||
|
};
|
||||||
|
img.src = URL.createObjectURL(file);
|
||||||
|
// Reset input so same file can be uploaded again
|
||||||
|
e.target.value = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Save Canvas Handler
|
||||||
|
const handleSaveCanvas = () => {
|
||||||
|
const canvas = canvasRef.current;
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.download = 'drawing.png';
|
||||||
|
link.href = canvas.toDataURL('image/png');
|
||||||
|
link.click();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="drawing-container">
|
<div className="drawing-container">
|
||||||
<div className="toolbar">
|
<div className="toolbar">
|
||||||
|
@ -194,6 +234,15 @@ const DrawingCanvas = () => {
|
||||||
<button onClick={() => setCurrentTool('circle')} className={`tool-button ${currentTool === 'circle' ? 'active' : ''}`}>⭕</button>
|
<button onClick={() => setCurrentTool('circle')} className={`tool-button ${currentTool === 'circle' ? 'active' : ''}`}>⭕</button>
|
||||||
<button onClick={handleUndo} className="tool-button" disabled={history.length === 0}>↺</button>
|
<button onClick={handleUndo} className="tool-button" disabled={history.length === 0}>↺</button>
|
||||||
<button onClick={handleRedo} className="tool-button" disabled={undoHistory.length === 0}>↻</button>
|
<button onClick={handleRedo} className="tool-button" disabled={undoHistory.length === 0}>↻</button>
|
||||||
|
<button onClick={() => fileInputRef.current.click()} className="tool-button">🖼️ Insert Image</button>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
ref={fileInputRef}
|
||||||
|
onChange={handleInsertImage}
|
||||||
|
/>
|
||||||
|
<button onClick={handleSaveCanvas} className="tool-button">💾 Save</button>
|
||||||
<div className="color-picker">
|
<div className="color-picker">
|
||||||
<ChromePicker color={color} onChangeComplete={(c) => setColor(c.hex)} />
|
<ChromePicker color={color} onChangeComplete={(c) => setColor(c.hex)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue