react-fabric —— 被 Fabric.js 官方推荐的 React 最佳实践

195 阅读6分钟

在 React 项目中处理复杂的 Canvas 交互,一直是让开发者头疼的难题。原生 Fabric.js 虽然强大,但在 React 的声明式编程模型下,手动管理对象生命周期、同步状态和处理事件流往往会导致代码碎片化。

今天,我们要重点推荐一个合合信息开源黑马项目:@cs-open/react-fabric

🌟 官方背书,血统纯正

react-fabric 的优秀并非自吹自擂。它已经正式被 Fabric.js 官方资源库(Fabric.js Resources) 收录并向全球开发者推荐。

🔗 官方推荐链接fabricjs.com/resources

在 Resources 页面中,你可以清楚地看到 @cs-open/react-fabric 作为高扩展性、复合型 React 封装库被列在显著位置。

🚀 AI 时代的宠儿:Cursor 评价第一

react-fabric.webp

在 AI 辅助编程领域,react-fabric 同样表现抢眼。根据开发者反馈和相关社区图片描述,该库在 Cursor (AI Code Editor) 的相关 React Canvas 库评价中位居第一

这意味着,当你使用 Cursor 进行代码补全或咨询绘图方案时,react-fabric 的结构化设计和类型完备性,使其成为了 AI 最推荐、生成代码最稳健的选择。

💎 核心优势:不仅仅是 Demo

很多开源库停留在“实验性”阶段,但 react-fabric 不同:

  1. 工业级稳定性:这不是一个简单的 Demo 项目!它目前正深度应用于大型商业项目中,经历了高并发、复杂场景的实战考验。
  2. 严苛测试保障:项目已经由专业测试人员进行了全方位的完善测试,包括性能压力测试、边界条件测试以及多端兼容性测试。
  3. 高度可扩展:采用复合样式(Composite style)设计,让你可以像写 React 组件一样组合复杂的 Canvas 元素,同时保留了直接操作底层 Fabric 实例的能力。

🏗️ 真实落地案例

该项目已在蜜蜂教育等大型教育科技平台中稳定运行。在教育场景这类对交互绘图、课件批注有极高要求的领域,react-fabric 展现了卓越的可靠性。


🛠️ 如何开始?

如果你正在寻找一个高性能、类型友好且能直接用于生产环境的 React Canvas 解决方案,请认准 react-fabric


✨ 核心特性

🎯 丰富的图形组件

  • 基础图形: 矩形、圆形、椭圆、线条、多边形、路径
  • 文本组件: 文本、可编辑文本、文本框
  • 图像组件: 背景图片、普通图片
  • 组合组件: 分组、对象集合
  • 自定义控件: 可拖拽控制点、工具栏

🖱️ 强大的交互功能

  • 自动缩放: 支持鼠标滚轮缩放,自动适应容器大小
  • 平移操作: 支持拖拽平移画布视图
  • 触摸支持: 完整的触摸设备支持,包括双指缩放和拖拽
  • 选择系统: 多选、框选、键盘快捷键支持
  • 拖拽操作: 对象拖拽、批量操作

📦 响应式设计

  • 自动适配: 画布自动撑满父容器,响应式调整
  • 触摸优化: 专为移动设备优化的触摸交互
  • 跨平台: 支持桌面端和移动端浏览器

💻 开发者友好

  • TypeScript: 完整的 TypeScript 类型支持
  • React 风格: 声明式 API,符合 React 开发习惯
  • 事件系统: 完整的事件回调,支持所有 Fabric.js 事件
  • 状态管理: 内置状态管理,支持受控和非受控模式

✨ 快速开始

安装

npm install @cs-open/react-fabric
# 或者
yarn add @cs-open/react-fabric
# 或者
pnpm add @cs-open/react-fabric

基础用法

import React from 'react'
import { ReactFabric, Rect, Text, Circle } from '@cs-open/react-fabric'

function App() {
  return (
    <div style={{ width: '100%', height: '500px' }}>
      <ReactFabric>
        <Rect left={100} top={100} width={200} height={100} fill="red" stroke="blue" strokeWidth={2} />
        <Circle left={300} top={150} radius={50} fill="green" />
        <Text left={150} top={250} text="Hello Fabric!" fontSize={20} fill="white" />
      </ReactFabric>
    </div>
  )
}

export default App

🎯 核心功能

自动缩放与平移

import { ReactFabric, useReactFabric } from '@cs-open/react-fabric'

function CanvasWithControls() {
  const { zoomIn, zoomOut, resetViewport, zoom } = useReactFabric()

  return (
    <div>
      <div className="toolbar">
        <button onClick={zoomIn}>放大</button>
        <button onClick={zoomOut}>缩小</button>
        <button onClick={() => resetViewport()}>重置</button>
        <span>缩放: {Math.round(zoom * 100)}%</span>
      </div>

      <ReactFabric zoomable={true} panAble={true} minManualZoom={0.1} maxManualZoom={5}>
        {/* 你的画布内容 */}
      </ReactFabric>
    </div>
  )
}

触摸设备支持

import { ReactFabric, PluginPinch } from '@cs-open/react-fabric'
import { PluginPinch } from '@cs-open/react-fabric/plugins'

function TouchCanvas() {
  return (
    <ReactFabric>
      {/* 你的画布内容 */}
      <PluginPinch />
    </ReactFabric>
  )
}

背景图片

import { ReactFabric, BackgroundImage } from '@cs-open/react-fabric'

function CanvasWithBackground() {
  return (
    <ReactFabric defaultCentered>
      <BackgroundImage src="/path/to/image.jpg" scaleToFit />
      {/* 其他图形元素 */}
    </ReactFabric>
  )
}

🔌 插件系统

内置插件

插件功能描述
PluginPinch触摸缩放支持双指缩放和拖拽操作
PluginFreeDraw自由绘制手绘路径和涂鸦功能
PluginFreeRect矩形绘制交互式矩形绘制工具
PluginFreeText文本工具点击添加可编辑文本
PluginGridLine网格辅助显示网格线辅助对齐
PluginMask遮罩效果创建遮罩和裁剪效果

使用插件

import { ReactFabric } from '@cs-open/react-fabric'
import { PluginPinch, PluginFreeDraw, PluginFreeRect, PluginGridLine } from '@cs-open/react-fabric/plugins'

function AdvancedCanvas() {
  return (
    <ReactFabric>
      {/* 触摸支持 */}
      <PluginPinch />

      {/* 自由绘制 */}
      <PluginFreeDraw
        onComplete={(path, { canvas }) => {
          console.log('绘制完成:', path)
        }}
      />

      {/* 矩形绘制工具 */}
      <PluginFreeRect
        fill={'red'}
        onComplete={(rect, { canvas }) => {
          console.log('矩形绘制完成:', rect)
        }}
      />

      {/* 网格线 */}
      <PluginGridLine />
    </ReactFabric>
  )
}

📦 组件 API

ReactFabric 组件

主要的画布容器组件,支持以下属性:

interface ReactFabricProps {
  // 基础属性
  width?: number
  height?: number
  className?: string
  style?: CSSProperties

  // 交互控制
  zoomable?: boolean // 是否可缩放
  panAble?: boolean // 是否可平移
  selection?: boolean // 是否可选择
  defaultSelection?: boolean // 默认选择状态
  defaultDraggable?: boolean // 默认拖拽状态

  // 缩放控制
  manualZoom?: number // 手动缩放倍数
  minManualZoom?: number // 最小缩放倍数
  maxManualZoom?: number // 最大缩放倍数
  defaultCentered?: boolean // 背景图是否居中

  // 事件回调
  onMouseDown?: (e: FabricPublicEvent) => void
  onMouseMove?: (e: FabricPublicEvent) => void
  onMouseUp?: (e: FabricPublicEvent) => void
  onMouseWheel?: (e: FabricPublicEvent) => void
}

图形组件

所有图形组件都支持对应的 Fabric.js 对象的所有属性和事件:

// 矩形
<Rect
  left={100}
  top={100}
  width={200}
  height={100}
  fill="red"
  stroke="blue"
  strokeWidth={2}
  onModified={(e) => console.log('矩形被修改', e.target)}
/>

// 圆形
<Circle
  left={200}
  top={200}
  radius={50}
  fill="green"
  onSelected={() => console.log('圆形被选中')}
/>

// 文本
<Text
  left={100}
  top={300}
  text="Hello World"
  fontSize={24}
  fill="black"
  fontFamily="Arial"
/>

// 图片
<Image
  left={300}
  top={300}
  src="/path/to/image.jpg"
  width={200}
  height={150}
/>

🎮 状态管理

useReactFabric Hook

import { useReactFabric } from '@cs-open/react-fabric'

function Toolbar() {
  const {
    // 状态
    canvas,
    zoom,
    manualZoom,
    isDragging,
    selection,

    // 方法
    zoomIn,
    zoomOut,
    resetViewport,
    setZoomable,
    setSelection,
    setDraggable,
  } = useReactFabric()

  return (
    <div className="toolbar">
      <button onClick={zoomIn}>放大</button>
      <button onClick={zoomOut}>缩小</button>
      <button onClick={() => resetViewport()}>重置</button>
      <span>缩放: {Math.round(zoom * 100)}%</span>
    </div>
  )
}

跨组件状态访问

ReactFabricProvider 是一个上下文提供程序,允许您从组件树中的任何位置访问流的内部状态,例如子组件,甚至在 ReactFabric 之外 元件。它通常用于应用程序的顶层。 在这种情况下,您可能需要使用 ReactFabricProvider 组件

import { ReactFabricProvider, useReactFabric } from '@cs-open/react-fabric'

function App() {
  return (
    <ReactFabricProvider>
      <Toolbar />
      <ReactFabric>{/* 画布内容 */}</ReactFabric>
    </ReactFabricProvider>
  )
}

function Toolbar() {
  const { zoomIn, zoomOut, resetViewport } = useReactFabric()
  // 可以在 ReactFabric 外部访问状态
}

🎨 高级用法

受控模式

import { useState } from 'react'
import { ReactFabric, Rect } from '@cs-open/react-fabric'

function ControlledCanvas() {
  const [rect, setRect] = useState({
    left: 100,
    top: 100,
    width: 200,
    height: 100,
    fill: 'red',
  })

  return (
    <ReactFabric>
      <Rect {...rect} onModified={e => setRect(e.target)} />
    </ReactFabric>
  )
}

非受控模式

import { ReactFabric, Rect, Group } from '@cs-open/react-fabric'

function UncontrolledCanvas() {
  return (
    <ReactFabric>
      <Group>
        <Rect defaultLeft={100} defaultTop={100} defaultWidth={100} defaultHeight={100} fill="blue" />
      </Group>
    </ReactFabric>
  )
}

DOM 集成

结合 floating-ui 可以轻松实现 dom 控件

import { ReactFabric, Rect } from '@cs-open/react-fabric'

function CanvasWithDOM() {
  return (
    <ReactFabric>
      <Rect left={100} top={100} width={200} height={100}>
        <div className="tooltip">这是一个提示框</div>
      </Rect>
    </ReactFabric>
  )
}

结语

选对工具,开发效率提升 200%。既然 Fabric.js 官方已经帮你选好了,Cursor 评价也拿了第一,还有大型项目背书,你还在犹豫什么?赶快在你的下一个项目中尝试 react-fabric 吧!