当前位置:首页 > React

react 如何使用canvas

2026-02-26 05:25:45React

在 React 中使用 Canvas

React 中可以通过 useRefuseEffect 结合原生 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;

处理动态绘图

对于需要响应状态变化的绘图,可以将状态添加到依赖数组中:

react 如何使用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} />;
}

处理用户交互

添加事件监听器处理用户输入:

react 如何使用canvas

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 应用,考虑以下优化方式:

  • 使用 shouldComponentUpdateReact.memo 避免不必要的重渲染
  • 将 Canvas 操作与 React 状态更新分离
  • 对于静态内容,可以考虑离屏 Canvas
  • 使用 useCallback 包装事件处理函数

常用 Canvas 库

如果项目需要更高级的功能,可以考虑这些 React Canvas 库:

  • react-konva
  • react-canvas
  • react-art
  • fabric.js (通过 React 封装使用)

分享给朋友:

相关文章

如何生成react代码

如何生成react代码

使用 Create React App 生成项目 安装 Node.js 后,通过命令行工具运行以下命令创建新项目: npx create-react-app my-app cd my-app npm…

react如何开发组件

react如何开发组件

React 组件开发基础 React 组件分为函数组件和类组件两种形式。函数组件是现代 React 开发的主流方式,结合 Hooks 可以实现完整功能。 函数组件示例: function Gr…

react如何迭代

react如何迭代

在 React 中迭代数组或对象 React 提供了多种方式来处理数组或对象的迭代,以下是常见的方法: 使用 map 方法迭代数组 map 是 JavaScript 数组的内置方法,常用于在 Rea…

react如何同步

react如何同步

React 同步状态管理方法 在 React 中实现同步状态管理,可以通过以下多种方式实现: 使用 useState 和 useEffect 钩子 通过 useState 定义状态,使用 useE…

react如何注销

react如何注销

React 组件的注销方法 在 React 中,组件的注销通常指的是在组件卸载时执行清理操作,例如取消订阅、清除定时器或释放资源。以下是几种常见的方法: 使用 useEffect 钩子的清理函数…

react如何代码优化

react如何代码优化

减少不必要的重新渲染 使用 React.memo 包装函数组件以避免在 props 未变化时重新渲染。对于类组件,可以通过 shouldComponentUpdate 或继承 PureComponen…