什么是Fabric.js
简介
什么是Fabric.js ?
Fabric.js 是一个可以简化 canvas 程序编写的库,在原生 canvas 之上提供了交互式对象模型,为 canvas 提供所缺少的对象模型, svg 解析器, 交互和一整套其他不可或缺的工具,通过简洁的 api 就可以在画布上进行丰富的操作。
为什么要使用Fabric.js ?
canvas 提供一个好的画布能力, 但是 api 不够友好。绘制简单图形其实还可以, 不过做一些复杂的图形绘制, 编写一些复杂的效果,就不是那么方便了。Fabric.js 就是为此而开发,它主要就是用对象的方式去编写代码。
Fabric.js 能做的事情
- 在canvas 上创建、填充图形(包括图片、文字、规则图形和复杂路径组成图形)。
- 给图形填充渐变颜色。
- 组合图形(包括组合图形、图形文字、图片等)。
- 设置图形动画及用户交互。
- 生成JSON, SVG 数据等。
- 生成Canvas 对象自带拖拉拽功能。
起步
安装
npm 安装
1 | npm install fabric --save |
通过cdn引用
1 | <script src="https://cdn.jsdelivr.net/npm/fabric@5.3.0/dist/fabric.min.js"></script> |
使用
绘制一个简单的图形
Fabric 提供了 7 种基础形状:
- fabric.Circle (圆)
- fabric.Ellipse (椭圆)
- fabric.Line (线)
- fabric.Polyline (多条线绘制成图形)
- fabric.triangle (三角形)
- fabric.Rect (矩形)
- fabric.Polygon (多边形)
圆和矩形:
1 | <script src="https://cdn.jsdelivr.net/npm/fabric@5.2.1/dist/fabric.min.js"></script> |
我们可以通过以下属性设置,决定是否可以对相关元素进行交互
1 | c.selection = false; // 禁止所有选中 |
绘制图片
主要有通过url 和 img 标签绘制两种方式
1 | //通过url绘制图片 |
通过自定义的路径绘制
在此之前我们需要了解几个参数的含义:
- M : “move”移动到某点
- L : “line”画线 x,y
- C : “curve”曲线
- A : “arc”弧
- Z : 闭合路径(类似 PS 中的创建选区)
1 | let customPath = new fabric.Path("M 0 0 L 300 100 L 170 100 z"); |
可以看到通过路径绘制,我们可以制作非常复杂的图形(但是一般用不到,我们一般用它来解析 SVG 后拿到 path 复原图形)
动画
第一个参数是动画的属性,第二个参数是动画的最终位置,第三个参数是一个可选的对象,指定动画的细节:持续时间,回调,动效等。
参数:
duration 默认为 500ms。可以用来改变动画的持续时间。
from 允许指定动画属性的起始值(如果我们不希望使用当前值)。
onComplete 动画结束之后的回调。
easing动效函数。
官网demo:
绝对动画
1 | const rect = new fabric.Rect({ |
相对动画(第二个参数通过+=,-=等来决定动画的最终效果)
1 | const rect = new fabric.Rect({ |
定义动画的动效函数
默认情况下,动画使用“easeInSine”动效执行。如果这不是你需要的,fabric 为我们提供了很多内置动画效果, fabric.util.ease 下有一大堆动效的选项。
常用的有easeOutBounce,easeInCubic,easeOutCubic,easeInElastic,easeOutElastic,easeInBounce 和easeOutExpo 等
1 | rect.animate("left", 100, { |
图像滤镜
目前Fabric 为我们提供了以下内置滤镜:
- Blur 模糊
- Brightness 亮度
- ColorMatrix 颜色矩阵
- Contrast 对比
- Convolute 卷积
- Gamma 伽玛
- Grayscale 灰度
- HueRotation 色调旋转
- Invert 倒置
- Noise 噪音
- Pixelate 像素化
- RemoveColor 移除颜色
- Resize 调整大小
- Saturation 饱和
单个滤镜
1 | fabric.Image.fromURL(require("https://images.unsplash.com/photo-1682695795798-1b31ea040caf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80"), (img) => { |
叠加滤镜
“filters” 属性是一个数组,我们可以用数组方法执行任何所需的操作:移除滤镜 (pop,splice,shift),添加滤镜 (push,unshift,splice),甚至可以组合多个滤镜。当我们调用 applyFilters 时,“filters” 数组中存在的任何滤镜将逐个应用,所以让我们尝试创建一个既色偏又明亮 ( Brightness ) 的图像。
1 | fabric.Image.fromURL(require("./aaa.jpeg"), (img) => { |
可以看到多个滤镜的效果叠加显示了,当然 Fabric 还支持自定义滤镜
颜色
无论你是使用十六进制,RGB 或 RGBA 颜色,Fabric 都能处理的很好
定义颜色
1 | new fabric.Color("#f55"); |
颜色转换
1 | new fabric.Color('#f55').toRgb(); // "rgb(255,85,85)" |
我们还可以用另一种颜色叠加,或将其转换为灰度版本。
1 | let redish = new fabric.Color("#f55"); |
定义颜色
1 | new fabric.Color("#f55"); |
渐变
Fabric 通过 setGradient 方法支持渐变,在所有对象上定义。调用 setGradient(‘fill’, { … })就像设置一个对象的“fill”值一样。
1 | const circle = new fabric.Circle({ |
文本
fabric.Text 对象对于文本,提供了比 canvas 更丰富的功能,包括:
支持多行Multiline support 不幸的是,原生文本方法忽略了新建一行。
文本对齐Text alignment 左,中,右。使用多行文本时很有用。
文本背景Text background 背景也支持文本对齐。
文字装饰Text decoration 下划线,上划线,贯穿线。
行高Line Height 在使用多行文本时有用。
字符间距Char spacing 使文本更紧凑或更间隔。
子范围Subranges 将颜色和属性应用到文本对象的子对象中。
多字节Multibyte 支持表情符号。
交互式画布编辑On canvas editing 可以直接在画布上键入文本。
事件
fabric 中通过 on 方法来初始化事件,off 方法用来删除事件。
常用的事件有以下:
mouse:down 鼠标被按下
object:add 对象被添加
after:render 渲染完成
还有一大堆:
鼠标事件: mouse: down , mouse: move 和 mouse: up…
选择相关的事件:before: selection: cleared, selection: created, 详细的可以查看官方文档
1 | canvas.on("mouse:down", function(options) { |
Fabric 允许将侦听器直接附加到 canvas 画布中的对象上。
1 | let rect = new fabric.Rect({ left: 100, top: 100, width: 200, height: 100, fill: "green" }); |
自由绘画
Fabric canvas 的 isDrawingMode 属性设置为 true 即可实现自由绘制模式.这样画布上的点击和移动就会被立刻解释为铅笔或刷子。
1 | canvas.isDrawingMode = true; |
fabric.js 与 konva 对比
fabric.js 的优点(star:24K)
比较老牌,常用的转换(放大、缩小、拖拽)都已经封装好了,特别适合用 Canvas 写交互性的界面
内置了丰富的笔刷,基本的对齐、标线等功能齐全
代码集成度比较高,内置了可交互富文本(纯Canvas 实现)
fabric.js 的缺点
由于库本身集成了很多功能点,代码包的大小偏大(压缩后308 kB)
细节功能还需要完善,比如标线系统实现相对简单, 竖向文字等
konva 的优点(star:8k)
使用TypeScript 编写,TS 原生支持
渲染分层比较清晰,Stage -> Layer -> Group -> Shape
代码简洁、干净,易于阅读
核心代码精简,代码包较小(压缩后155 kB)
konva 的缺点
部分功能实现基于DOM(富文本)
后起之秀,周边生态还比较薄弱
相关链接
fabric.js 官网链接:http://fabricjs.com/
fabric.js github链接:https://github.com/fabricjs/
konva.js官网链接:https://konvajs.org/
konva.jsgithub链接:https://github.com/konvajs/konva
md中不太好写demo,很多没有展示出效果,后面会做个组件库来完善(给自己花个饼🫓)

