Fabric.js 入门教程:扩展自定义对象的完整实践(V6)

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创
  • 📢作者格言:新的征程,用爱发电,去丈量人心,是否能达到人机合一?

Fabric.js 入门教程:扩展自定义对象的完整实践

Fabric.js 是一个功能强大的 HTML5 Canvas 库,用于构建交互式、可编辑的图形应用程序。本篇文章将通过逐步扩展 Fabric.js 的对象,创建一个名为 ComNode 的自定义节点组件,帮助读者从入门到精通 Fabric.js 的对象扩展功能。

这里有教程,可以随时收藏翻阅,一个V6版本的中文档手册,目前目录如下,大家可以点击 FabricJS.cc 访问, 下面全部代码可在 FabricJs playground 内访问。


一、基础概念与准备

Fabric.js 提供了一个基础框架,可以扩展它的内置对象,如 Rect(矩形)、Circle(圆形)等。在这篇文章中,我们将基于 Rect 扩展一个新的对象,ComNode,它包含以下功能:

  1. 额外的 icon 属性。
  2. 支持自定义控制点(Anchors)。
  3. 可序列化和反序列化。

环境准备

确保你已经安装 Fabric.js:

bash 复制代码
npm install fabric

在代码中引入 Fabric.js 和基础模块:

typescript 复制代码
import {
  classRegistry,
  Control,
  ObjectEvents,
  Rect,
  RectProps,
  SerializedRectProps,
  TClassProperties,
  TOptions,
} from 'fabric';

二、构造自定义对象 ComNode

1. 定义对象的属性

Fabric.js 使用属性作为核心控制点。我们将添加 icon 属性:

typescript 复制代码
interface UniqueComNodeProps {
  icon: string; // 自定义属性
}

同时,定义序列化所需的扩展接口:

typescript 复制代码
export interface SerializedComNodeProps
  extends SerializedRectProps,
    UniqueComNodeProps {}

2. 设置默认值

通过静态属性为新对象设定默认值:

typescript 复制代码
export const comNodeDefaultValues: Partial<TClassProperties<ComNode>> = {
  icon: '',
};

3. 创建 ComNode 类

接下来,创建一个继承自 Rect 的类:

typescript 复制代码
export class ComNode<
    Props extends TOptions<ComNodeProps> = Partial<ComNodeProps>,
    SProps extends SerializedComNodeProps = SerializedComNodeProps,
    EventSpec extends ObjectEvents = ObjectEvents
  >
  extends Rect<Props, SProps, EventSpec>
  implements RectProps {
  
  declare icon: string;

  static type = 'ComNode';
  static cacheProperties = [...Rect.cacheProperties, 'icon'];

  constructor(options?: Props) {
    super();
    Object.assign(
      this,
      ComNode.ownDefaults,
      (this.constructor as typeof ComNode).createAnchors()
    );
    this.setOptions(options);
  }

  setIcon(value: string) {
    this.icon = value;
  }

  getIcon(): string {
    return this.get('icon');
  }
}

这里的 constructor 初始化了默认属性和控制点(Anchors)。


三、添加控制点与方法

1. 创建自定义控制点

Fabric.js 提供了控制点功能,可以通过 AnchorControl 定义。示例中使用静态方法 createAnchors 创建默认控制点:

typescript 复制代码
static createAnchors(): { anchors: Record<string, AnchorControl> } {
  return { anchors: createObjectDefaultControls() };
}

2. 自定义渲染逻辑

覆盖 _render 方法,在节点绘制时自定义渲染逻辑:

typescript 复制代码
_render(ctx: CanvasRenderingContext2D) {
  super._render(ctx);
  // 在这里添加图标或其他绘制逻辑
}

四、实现序列化和反序列化

1. 序列化

Fabric.js 对象的序列化通过 toObject 方法实现:

typescript 复制代码
toObject<SerializedComNodeProps>(
  propertiesToInclude: string[] = []
): SerializedComNodeProps {
  return super.toObject([...propertiesToInclude, 'icon']);
}

2. 反序列化

通过 fromObject 实现反序列化:

typescript 复制代码
static fromObject<T extends TOptions<SerializedComNodeProps>>(object: T) {
  return super._fromObject<ComNode>(object);
}

五、注册到 ClassRegistry

Fabric.js 使用 classRegistry 注册扩展对象:

typescript 复制代码
classRegistry.setClass(ComNode);

这样,我们可以在项目中直接使用 ComNode


六、完整代码与使用示例

以下是完整代码:

typescript 复制代码
// 导入依赖
import {
  classRegistry,
  Control,
  ObjectEvents,
  Rect,
  RectProps,
  SerializedRectProps,
  TClassProperties,
  TOptions,
} from 'fabric';
import { AnchorControl, createObjectDefaultControls } from './AnchorControl';

// 定义属性
interface UniqueComNodeProps {
  icon: string;
}

export interface SerializedComNodeProps
  extends SerializedRectProps,
    UniqueComNodeProps {}

export class ComNode<...> extends Rect {
  ...
}

// 注册类
classRegistry.setClass(ComNode);

使用示例

在 Canvas 中实例化:

typescript 复制代码
const canvas = new fabric.Canvas('canvas');

const node = new ComNode({
  left: 100,
  top: 100,
  width: 50,
  height: 50,
  icon: '📦',
  fill: 'blue',
});

canvas.add(node);

七、总结

通过扩展 Rect,我们实现了一个功能丰富的自定义节点组件 ComNode,并具备以下特性:

  1. 自定义属性(如 icon)。
  2. 灵活的控制点机制。
  3. 序列化与反序列化支持。

Fabric.js 的设计使得扩展对象变得简单,同时可以与其原生功能无缝集成。希望本文能为你提供一个清晰的 Fabric.js 入门思路,帮助你创建更多强大的图形组件!

你学废了吗?

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?

相关推荐
火星牛1 小时前
AI IDE试用(一)
javascript·ide
jump_jump3 小时前
基于 Squoosh WASM 的浏览器端图片转换库
前端·javascript·性能优化
longerxin20204 小时前
在 Linux 上使用 SCP 将文件传输到 Windows(已开启 SSH)
linux·运维·ssh
zhaotiannuo_19986 小时前
渗透测试之docker
运维·docker·容器
王正南7 小时前
kali-linux 虚拟机连接安卓模拟器
android·linux·运维·虚拟机连接模拟器·安卓模拟器,linux虚拟机
三不原则7 小时前
故障案例:容器启动失败排查(AI运维场景)——从日志分析到根因定位
运维·人工智能·kubernetes
吳所畏惧7 小时前
Linux环境/麒麟V10SP3下离线安装Redis、修改默认密码并设置Redis开机自启动
linux·运维·服务器·redis·中间件·架构·ssh
yueguangni7 小时前
sysstat 版本 10.1.5 是 CentOS 7 的默认版本,默认情况下确实不显示 %wait 字段。需要升级到新版sysstat
linux·运维·centos
阿珊和她的猫8 小时前
IIFE:JavaScript 中的立即调用函数表达式
开发语言·javascript·状态模式
funfan05178 小时前
【运维】MySQL数据库全量备份与恢复实战指南:从入门到精通
运维·数据库·mysql