react 如何使用canvas
在 React 中使用 Canvas
React 中可以通过 useRef 和 useEffect 结合原生 Canvas API 实现绘图功能。以下是一个完整的实现方法:
创建 Canvas 组件
import React, { useRef, useEffect } from 'react';
function Canvas() {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
// 绘制矩形
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 150, 100);
}, []);
return (
<canvas
ref={canvasRef}
width={300}
height={200}
/>
);
}
export default Canvas;
处理动态绘图
对于需要响应状态变化的绘图,可以将状态添加到依赖数组中:

function DynamicCanvas({ color }) {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = color;
ctx.fillRect(10, 10, 150, 100);
}, [color]);
return <canvas ref={canvasRef} width={300} height={200} />;
}
实现动画效果
使用 requestAnimationFrame 实现动画:
function AnimatedCanvas() {
const canvasRef = useRef(null);
const positionRef = useRef(0);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
let animationId;
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(positionRef.current, 50, 50, 50);
positionRef.current += 1;
if (positionRef.current < canvas.width) {
animationId = requestAnimationFrame(animate);
}
};
animate();
return () => cancelAnimationFrame(animationId);
}, []);
return <canvas ref={canvasRef} width={300} height={200} />;
}
处理用户交互
添加事件监听器处理用户输入:

function InteractiveCanvas() {
const canvasRef = useRef(null);
const [circles, setCircles] = useState([]);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const handleClick = (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
setCircles([...circles, { x, y }]);
};
canvas.addEventListener('click', handleClick);
return () => canvas.removeEventListener('click', handleClick);
}, [circles]);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
circles.forEach(circle => {
ctx.beginPath();
ctx.arc(circle.x, circle.y, 20, 0, 2 * Math.PI);
ctx.fill();
});
}, [circles]);
return <canvas ref={canvasRef} width={500} height={400} />;
}
性能优化建议
对于复杂的 Canvas 应用,考虑以下优化方式:
- 使用
shouldComponentUpdate或React.memo避免不必要的重渲染 - 将 Canvas 操作与 React 状态更新分离
- 对于静态内容,可以考虑离屏 Canvas
- 使用
useCallback包装事件处理函数
常用 Canvas 库
如果项目需要更高级的功能,可以考虑这些 React Canvas 库:
- react-konva
- react-canvas
- react-art
- fabric.js (通过 React 封装使用)






