我正在尝试在我的 MERN 堆栈应用程序中创建一个白板。
import React, { useEffect, useRef, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useSelector } from 'react-redux';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import DeleteIcon from '@mui/icons-material/Delete';
import PermMediaIcon from '@mui/icons-material/PermMedia';
import './Whiteboard.css';
export default function Whiteboard({ canvasRef, socketRef }) {
const params = useParams();
const navigate = useNavigate();
const colorsRef = useRef(null);
const currentUser = useSelector((state) => state.auth);
const [canvasCurrent, setCanvasCurrent] = useState(null);
const colors = document.getElementsByClassName('color');
const [color,setColor]=useState('black')
const onColorUpdate = (e) => {
setColor(e.target.className.split(' ')[1]);
};
for (let i = 0; i < colors.length; i++) {
colors[i].addEventListener('click', onColorUpdate);
}
const [isDrawing, setIsDrawing] = useState(false);
const [shapes, setShapes] = useState(
JSON?.parse(localStorage?.getItem(`${params.workspaceId}-drawing`)) || []
);
const [currentStroke, setCurrentStroke] = useState([]);
function drawShapes() {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
shapes.forEach((shape) => {
ctx.beginPath();
ctx.moveTo(shape?.points[0]?.x, shape?.points[0]?.y);
shape.points.forEach((point) => {
ctx.lineTo(point.x, point.y);
});
ctx.strokeStyle = shape.color;
ctx.lineWidth = shape.strokeWidth;
ctx.stroke();
});
if (currentStroke.length > 0) {
ctx.beginPath();
ctx.moveTo(currentStroke[0].x, currentStroke[0].y);
currentStroke.forEach((point) => {
ctx.lineTo(point.x, point.y);
});
ctx.strokeStyle = color;
ctx.lineWidth = 2;
ctx.stroke();
}
requestAnimationFrame(drawShapes);
}
useEffect(() => {
drawShapes();
}, [shapes, drawShapes]);
socketRef.current.on('drawingChange', ({ drawingData }) => {
localStorage?.setItem(`${params.workspaceId}-drawing`, JSON.stringify([...shapes,drawingData]));
setShapes([...shapes,drawingData])
});
socketRef.current.on('codeChange', ({ code }) => {
localStorage?.setItem(`${params.workspaceId}-code`, code);
});
const clearCanvas = () => {
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = '#fff';
context.fillRect(0, 0, canvas.width, canvas.height);
};
const downloadCanvas = () => {
const canvas = canvasRef.current;
console.log(canvas)
setCanvasCurrent(canvas.toDataURL());
const image = canvas.toDataURL('png');
const link = document.createElement('a');
const time = new Date();
const imageName = time.toISOString();
link.download = `${params.workspaceId}-${imageName}.png`;
link.href = image;
link.click();
setTimeout(() => {
const canvas = canvasRef.current;
const context = canvas.getContext('2d');
const image = new Image();
image.onload = function () {
context.fillStyle='#fff'
context.drawImage(image, 0, 0);
};
image.src = canvasCurrent;
}, 2000);
};
function handleMouseDown(e) {
// Start a new shape
setIsDrawing(true);
setCurrentStroke([{ x: e.clientX, y: e.clientY }]);
}
function handleMouseMove(e) {
if (isDrawing) {
setCurrentStroke([...currentStroke, { x: e.clientX, y: e.clientY }]);
}
}
function handleMouseUp() {
setIsDrawing(false);
const newShape = {
type: "freehand",
points: currentStroke,
color: color,
strokeWidth: 2
};
localStorage?.setItem(`${params.workspaceId}-drawing`, JSON.stringify([...shapes,newShape]));
socketRef.current.emit('drawingChange', {
drawingData: newShape,
roomId: params.workspaceId,
});
setShapes([...shapes, newShape]);
setCurrentStroke([]);
}
function handleTouchStart(e) {
handleMouseDown(e.touches[0]);
}
function handleTouchMove(e) {
handleMouseMove(e.touches[0]);
}
function handleTouchEnd(e) {
handleMouseUp(e);
}
return (
<div>
<canvas width={window.innerWidth}
height={window.innerHeight}
ref={canvasRef}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd} className='whiteboard' style={{backgroundColor:"white"}} />
<div ref={colorsRef} className='colors'>
<div className='color black' />
<div className='color red' />
<div className='color green' />
<div className='color blue' />
<div className='color yellow' />
{/* Create a Tooltip with Erase */}
<Tooltip title='Erase'>
<div className='color white' />
</Tooltip>
{/* Create a vertical line */}
<div className='vertical-line' />
{/* Create a ToolTip with IconButton to Clear */}
<Tooltip title='Clear'>
<IconButton
onClick={clearCanvas}
className='clear'
aria-label='clear'
sx={{ color: '#03256C' }}
>
<DeleteIcon />
</IconButton>
</Tooltip>
{/* Create a ToolTip with IconButton to Download */}
<Tooltip title='Save as PNG'>
<IconButton
onClick={downloadCanvas}
className='download'
aria-label='download'
sx={{ color: '#03256C' }}
>
<PermMediaIcon />
</IconButton>
</Tooltip>
</div>
</div>
);
}
这是我的代码。它只是我代码的一部分,因为整个代码太大了。 在这个白板上,我有不同颜色的笔。用户可以在画布上画画。
我在下载选项中遇到问题。 在画布上,背景颜色为白色。 但是,当用户下载他的画布时,下载图像的背景颜色变成黑色。 如何将下载图像的背景颜色设置为白色。