FabricJS 前端绘图库使用总结(一)

JavaScript021

FabricJS 前端绘图库使用总结(一),第1张

使用Fabric 一段时间了,总得来说,是一款非常强大的矢量图工具,官方文档也算丰富,但文档组织形式不太好,而且少部分api设计不太一致,还是需要整理一下。

canvas是最基础的对象,针对

标签做的封装,可以管理内部绘制的所有对象。

这个canvas对象,并不是DOM里的元素,如果需要控制dom,或者对应的context,还是需要自己获取的。

新建canvas对象的时候,可以指定宽高:

这里指定的宽高会覆盖css中设置的。注意这种创建对象的形式,Fabric.js里基本上都是类似的,类名表示要创建的对象类型,第一个参数是必要的数据,第二个参数是各种选项。

所有对canvas的修改,包括在其中添加删除对象,以及对象参数的修改,都需要调用渲染方法才能显示出来:

线条-Line, 圆-Circle, 矩形-Rectangel等几何图形,都属于基本形状。

所有基本形状,都有对应的类,这样就可以通过类实例的属性和方法来控制它们的位置、颜色、大小等样式。所有类都继承自Object类,有一些公共的属性和方法。

下面是画线的例子(给出两个顶点坐标):

画圆的例子(顶点和半径是在选项里的),这里left和top其实就是(x,y),应该是借用了css里的命名。

从这里可以看出,和创建canvas类似,第一个参数是这个类专用的(比如画直线的时候传的起止点坐标),第二个参数是通用选项,如果没有专用参数,那么第一个参数就直接是通用选项。所有创建完的形状,只有通过canvas的add方法加入创景,才能显示出来。

left和top是每种Object都有的属性,至于它到底指图形中哪一个点的坐标,由originX和originY这组参数决定,它们相当于文本编辑软件里的对齐方式,originX有三种可选值:left,center, right;originY也有三种可选值:top, center, bottom。

它们的示意图如下:

不同锚点示意

如果希望每种对象缺省原点都在中心,可以这样设置:

width和height也是可以直接存取的属性,顾名思义,表示长和宽(所有形状都是有外接矩形的,所以可以用长和宽来控制大小)。

除了上面那几个可以直接存取的属性,大部分属性需要使用get/set方法读写,比如:

网上有些文章会写成line.stroke=color,或者line.setProperty('stroke',color)这样的形式,都是不能生效的,可能是早期版本的表达方式。

Image跟其他形状类似,都是Object的子类,最大的区别在于,图像文件的加载是异步的,所以对Image的后续操作,都要在回调中完成。

常用的js绘图库有:

D3.js:一个功能强大的数据可视化库,支持吸附闭合等功能。

Raphael.js:一个轻量级的交互绘图库,支持实时显示角度和长度。

Fabric.js:一个强大的交互绘图库,支持实时检测垂直和平行等功能。

p5.js:一个用于创作艺术和交互作品的库,可以实现吸附闭合等功能。

最近在项目中使用Cytoscape.js、D3.js和DataV等前端绘图库。

图形常见的操作有拖拽、缩放、平移等。

页面出现这些动作事件后,这些绘图库都会抛出一个hook,然我们有机会根据业务需求,在合适的时机完成图形操作。

问题就来了,例如拖拽事件,用户拖拽一个节点是一个持续的过程,浏览器有可能1s中抛出好几百个“drag”事件。

如果每个“drag”事件,我们都去做绘制图形相关的计算,那么会浪费很多计算资源。

因为浏览器一般1s中最多也就绘制60次,也就是说,尽管我们1秒钟计算了好几百次,只有其中60次的计算结果能够展示在界面上,大部分计算都是无效的,白白浪费了计算资源。

那么有什么优化方法呢?

首先想到的是debounce或者throttle函数, 能够降低回调函数的执行频率。但缺点是,时间参数门限的选取比较纠结,参数大了,用户操作会有卡顿延时感;参数门限小了话,又有可能浪费性能。

最好的办法就是浏览器要绘制界面之前,完成相关的计算,这样不多不少,每个计算结果都能得到展示。

所以,最后的答案来了 —— window.requestAnimationFrame(callback) 。这个web API是前端应用绘图库的必备API,能够让用户有丝滑的交互体验,同时让计算开销降到最低。