react 如何切canvas
在 React 中集成 Canvas
React 中可以通过 useRef 和 useEffect 钩子直接操作 Canvas。创建一个 canvas 元素的引用,在组件挂载后通过 getContext 获取绘图上下文。
import React, { useRef, useEffect } from 'react';
function CanvasComponent() {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 50);
}, []);
return <canvas ref={canvasRef} width={200} height={200} />;
}
动态调整 Canvas 尺寸
为避免 Canvas 渲染模糊,需根据设备像素比(DPR)调整宽高。通过 window.devicePixelRatio 缩放 Canvas 的实际尺寸,同时用 CSS 控制显示尺寸。

useEffect(() => {
const canvas = canvasRef.current;
const dpr = window.devicePixelRatio || 1;
canvas.width = canvas.clientWidth * dpr;
canvas.height = canvas.clientHeight * dpr;
const ctx = canvas.getContext('2d');
ctx.scale(dpr, dpr);
}, []);
使用第三方库优化绘制
对于复杂场景,可使用库如 react-konva 或 fabric.js 简化 Canvas 操作。react-konva 提供声明式 API,支持图层管理和事件处理。

import { Stage, Layer, Rect } from 'react-konva';
function KonvaExample() {
return (
<Stage width={300} height={300}>
<Layer>
<Rect x={10} y={10} width={50} height={50} fill="red" />
</Layer>
</Stage>
);
}
性能优化策略
频繁绘制的动画场景中,使用 requestAnimationFrame 替代 setInterval。清理函数中取消动画帧以避免内存泄漏。
useEffect(() => {
let animationId;
const animate = () => {
const ctx = canvasRef.current.getContext('2d');
// 绘制逻辑
animationId = requestAnimationFrame(animate);
};
animate();
return () => cancelAnimationFrame(animationId);
}, []);
响应式 Canvas 设计
监听窗口大小变化时,需重新计算 Canvas 尺寸。使用 ResizeObserver 或 window.addEventListener 实现自适应布局。
useEffect(() => {
const handleResize = () => {
const canvas = canvasRef.current;
canvas.width = canvas.clientWidth * window.devicePixelRatio;
canvas.height = canvas.clientHeight * window.devicePixelRatio;
// 重绘内容
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);






