LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

Fabric.js介绍

admin
2023年5月23日 10:1 本文热度 777

Fabric.js是什么

Fabric.js 是一个简化HTML5 Canvas开发的Javascript库,Fabric.js提供了HTML5 Canvas本身缺失的对象模型、交互层、SVG解析器以及其他一整套工具。它是一个完全开源的项目,在MIT下获得授权,多年来一直在维护,近期要发布4.0版本,支持自定义controls。

Fabric.js能做什么

在Canvas画布上创建、填充图形(包括图片、文字、规则图形和复杂路径组成图形)。
给图形填充渐变颜色。
组合图形(包括组合图形、图形文字、图片等)。
设置图形动画及用户交互,生成的对象自带拖拉拽功能。
JSON, SVG数据的序列化和反序列化。

为什么使用Fabric.js

HTML5 Canvas提供了完整的画布,可以轻松的在画布上绘制简单的图形、制作简单的动画,但是HTML5 Canvas提供的API过于低级,且操作基于上下文,因此在绘制复杂图形或者需要实现用户交互时,就显得不是那么方便了。Fabric.js在HTML5 Canvas原生API之上,提供完整的对象模型,由Fabric.js来管理HTML5 Canvas画布的状态和渲染,用户基于具体的对象,来编写代码,完成所需功能的开发(类似于面向过程和面向对象)。“Talk is cheap. Show me the code”,下面通过代码来看看用HTML5 Canvas原生方法和用Fabric.js分别实现在画布上画一个矩形这一功能。

用HTML5 Canvas的原生方法实现

// 获取canvas元素

var canvasEl = document.getElementById('c');

// 获取上下文

var ctx = canvasEl.getContext('2d');

// 设置填充颜色

ctx.fillStyle = 'red';

// 在100,100点创建20x20的矩形

ctx.fillRect(100, 100, 20, 20);

在线演示地址:https://codepen.io/liblack/pen/LYpaMwa

用Fabric.js实现相同的功能:

// 创建原生canvas元素的包装类(‘c’canvas元素的id)

var canvas = new fabric.Canvas('c');

// 创建一个矩形对象

var rect = new fabric.Rect({

  left: 100,

  top: 100,

  fill: 'red',

  width: 20,

  height: 20

});

// 添加矩形到画布上

canvas.add(rect);

在线演示地址:https://codepen.io/liblack/pen/PoPLVwZ

由上面例子,可以看到使用HTML5 Canvas原生方法是对context(代表整个画布位图的对象)进行操作,而使用Fabric.js,我们是对对象操作,只需要去实例化对象,设置对象的属性,然后将它们添加到canvas中。到这里,可能还感受不到Fabric对比原生Canvas方法的优势,下面可以完成这样的功能,即在刚才绘制的矩形的基础上,将矩形位置移动到(10,10)点上。
这样的功能,在Canvas原生方法上实现,需要先把原来的矩形从画布上清除,然后在(10,10)位置重新绘制一个矩形,以此来实现矩形移动这样的功能。

// 擦除之前的矩形(这里是擦除了整个canvas区域)

ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);

// 重新绘制矩形

ctx.fillRect(20, 50, 20, 20);

听起来是不是很蹩脚?是的,使用Canvas原生方法时,就像是个带橡皮檫的笔刷,在画布上绘制图形时,是笔刷在画布上移动,绘制出的图形就是笔刷移动的整个痕迹,而想把绘制好的图形移动到其他地方,只好用橡皮檫擦掉,然后在新位置重新绘制。

相应的,使用Fabric.js实现该功能时,只需要改变矩形对象的属性,然后重新刷新(渲染)画布即可。

rect.set({ left: 20, top: 50 });

canvas.renderAll();


Canvas对象

fabric.Canvas作为元素的包装器,创建fabric.Canvas对象如下:

var canvas = new fabric.Canvas('...')


它接收一个元素的id,并返回一个fabric.Canvas 的实例。fabric.Canvas对象,并不是DOM里的元素,如果需要直接控制DOM,或者对应的context,需要通过相应API去获取。

var canvasElement = document.getElementById(canvasEle);

var ctx = canvasElement.getContext("2d");

fabric.Canvas对象负责管理画布上绘制的所有对象,可以将对象添加到fabric.Canvas对象,也可以从fabric.Canvas获取或删除对象。

var canvas = new fabric.Canvas('c');

var rect = new fabric.Rect();

canvas.add(rect); // 添加对象

canvas.item(0); ///获取之前添加的fabric.Rect(第一个对象)

canvas.getObjects(); ///获取画布上的所有对象(rect将是第一个也是唯一一个)

canvas.remove(rect); ///删除之前添加的对象删除


fabric.Canvas对象可以对画布进行配置。比如需要为整个画布设置背景颜色或图像?需要将所有内容剪裁到特定区域?设置不同的宽度/高度?指定画布是否是交互式的?所有这些选项(及其他)都可以在fabric.Canvas对象上进行设置,可以在创建时或之后进行设置。

var canvas = new fabric.Canvas('c', {

  backgroundColor: 'rgb(100,100,100,200)',

  selectionColor:'blue',

  selectLineWidth: 2

  // ...

});

// 或

var canvas = new fabric.Canvas('c');

canvas.setBackgroundImage('http://...');

canvas.onFpsupdate = function(){ /* ...... */ };

// ...


注意这种创建对象的形式,Fabric.js里基本上都是类似的,类名表示要创建的对象类型,第一个参数是必要的数据,第二个参数是各种选项。

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

canvas.renderAll();


Objects基本图形
Fabric.js提供了7种基本图形,下面是图形对应的类:

fabric.Circle

fabric.Ellipse

fabric.Line

fabric.Polygon

fabric.Polyline

fabric.Rect

fabric.Triangle


所有基本形状,都可以通过类实例的属性头椒ɡ纯刂扑堑奈恢谩⒀丈⒋笮〉妊健K欣喽技坛凶詅abric.Object类,有一些公共的属性和方法。

创建

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

var line =  new fabric.Line([x1, y1, x2, y2], {

    strokeWidth: 2, //线宽

    stroke: rgba(255,0,0,0.8), //线的颜色

    selectable: false

});

canvas.add(line);


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

var circle =  new fabric.Circle({

    radius: 2,

    left: left,

    top: top,

    originX: 'center',

    originY: 'center',

    fill: rgba(0,200,0,0.8), 

    strokeWidth: 1,

    stroke: rgba(255,0,0,0.8),

    selectable: false

});

canvas.add(circle);


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

控制

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

它们的示意图如下:
http://fabricjs.com/test/misc/origin.html

如果希望对象的默认原点在中心,可以这样设置:

fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center'


width和height也是可以直接存取的属性,顾名思义,表示长和宽(所有形状都是有外接矩形的,所以可以用长和宽来控制大小)。除了上面那几个可以直接存取的属性,大部分属性需要使用get/set方法读写,比如:

line.left = pointer.x;

line.top = pointer.y;

line.set('stroke', startColor);

line.set('height', 20);


Image对象

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

fabric.Image.fromURL('my_image.png', function(oImg) {

  // scale image down, and flip it, before adding it onto canvas

  oImg.scale(0.5).set('flipX, true);

  canvas.add(oImg);

});


Path对象

在Fabric.js中的Path代表了一个形状的轮廓,它可以被填充、描边和修改。Path由一系列的命令组成,本质上是模仿一支笔从一个点到另一个点。在“move”, “line”, “curve”, or “arc”等命令的帮助下,Path可以形成非常复杂的形状。而在Paths(PathGroup’s)组的帮助下,Path的能实现更多的复杂图形。
Fabric.js中的Path与SVG的 元素非常相似。它们使用相同的命令集,可以从 元素中创建,并将其序列化。我们稍后会更深入地研究序列化和SVG解析,但现在值得一提的是,实践中很少会手动创建Path实例。相反,更多的是使用Fabric.js的内置SVG解析器。
手工创建一个简单的Path对象。

var path = new fabric.Path('M 0 0 L 200 100 L 170 200 z');

path.set({ left: 120, top: 120 });

canvas.add(path);


实例化 fabric.Path 对象,传递给它一串路径指令。虽然看起来很隐蔽,但实际上很容易理解。”M “代表 “移动 “指令,告诉隐形笔要移动到0,0点。”L “代表 “线”,让笔画一条线到200,100点。然后,另一个 “L “代表 “线”,让笔画一条线到170,200点。最后,”z “告诉画笔关闭当前路径并最终确定形状。结果,得到的是一个三角形的形状。

由于 fabric.Path 就像 Fabric 中的其他对象一样,我们还可以改变它的一些属性。但我们还可以对它进行更多的修改。

...

var path = new fabric.Path('M 0 0 L 300 100 L 200 300 z');

...

path.set({ fill: 'red', stroke: 'green', opacity: 0.5 });

canvas.add(path);


实践中,更多是直接使用fabric.loadSVGfromString 或 fabric.loadSVGfromURL 方法来加载整个 SVG 文件,然后让 Fabric 的 SVG 解析器来完成所有 SVG 元素的解析工作,并创建相应的 Path 对象。

Events事件

事件驱动的架构是一个框架灵活性和可扩展性的基础。Fabric.js提供了一个广泛的事件系统,覆盖了低级的 “鼠标”事件到高级的对象事件。
这些事件使我们能够监控到到画布上发生的各种动作的不同时刻。比如想知道鼠标被按下的时间,只需监听”mouse:down”事件就可以了。想知道对象何时被添加到画布上,只需要监听”object:added “事件就在那里。

事件API非常简单,类似于jQuery、Underscore.js或其他流行的JS库。有on方法来初始化事件监听器,有off方法来移除事件监听器。

下面一个实际的例子。

var canvas = new fabric.Canvas('...');

canvas.on('mouse:down', function(options) {

  console.log(options.e.clientX, options.e.clientY);

});


上面例子演示了在canvas上添加”mouse:down”事件监听器,并给它设置事件处理程序,它将记录事件发生的坐标。事件处理程序会接收一个选项对象,它有两个属性:e—原始事件,和target—画布上的点击对象(如果有的话)。该事件在任何时候都是存在的,但目标只有在实际点击了画布上的某个对象后才会存在。target也只有在有意义的情况下才会传递给事件的处理程序,例如,对于 “mouse:down”事件,但对于 “after:render”事件(表示整个画布被重新绘制),target不会传递给事件处理程序。

canvas.on('mouse:down', function(options) {

  if (options.target) {

    console.log('一个对象被点击了!', options.target.type);

  }

});


如果你点击了一个对象,上面的例子会输出 “一个对象被点击了!”。还会显示被点击的对象类型。

那么,在Fabric.js中还有鼠标级的事件:“mouse:down”, “mouse:move”, 和”mouse:up”。通用的事件: “after:render”。选择相关的事件: “before:selection:cleared”,”selection:create”,”selection:cleared”。对象相关的事件: “object:moded”、”object:selected”、”object:moving”、”object:scaling”、”object:rotating”、”object:additional “和 “object:detter”。
注意,像”object:moving”(或”object:scaling”)这样的事件在每次对象移动(或缩放)时,即使是一个像素点的移动,也会连续地被触发。另一方面,像 “object:modified” 或 “selection:create”这样的事件只在操作(对象修改或选区创建)结束时才会被触发。如果将事件直接附加到画布上的(canvas.on(‘mouse:down’, …)),这意味着事件被覆盖到了canvas实例上。如果一个页面上有多个画布,可以给每个画布附加不同的事件监听器。它们都是独立互不影响的。
为了方便,Fabric.js将事件系统做得更进一步,允许直接将监听器附加到具体对象上。如下例子。

var rect = new fabric.Rect({ width: 100, height: 50, fill: 'green' });

rect.on('elected', function() {

  console.log('选择了一个矩形');

});

var circle = new fabric.Circle({ radius: 75, fill: 'blue' });

circle.on('selected', function() {

  console.log('选择了一个圆圈');

});


上述例子直接给矩形和圆的实例附加事件监听器,使用的是 “selected “事件,而不是 “object:selected”。同样的,可以在对象上使用 “modified”事件(当附加到canvas上时使用 “object:modified”)、”rotating”事件(当附加到canvas时使用 “object:rotating”)等等。

Groups组

fabric.Group是Fabric.js提供的强大的功能之一。使用Groups可以将任何Fabric对象组合成一个单一实体,这样就能够将这些对象作为一个单一的单元来处理。用鼠标将画布上的任意数量的Fabric对象进行组合,一旦组合后,这些对象都可以一起移动甚至修改。它们组成了一个组。我们可以对该组进行缩放、旋转,甚至改变其呈现属性—颜色、透明度、边框等。

下面创建一个由2个对象组成的组,即圆圈和文本。

var circle = new fabric.Circle({

  radius: 100,

  fill: '#eef',

  scaleY: 0.5,

  originX: 'center',

  originY: 'center'

});

var text = new fabric.Text('hello world', {

  fontSize: 30,

  originX: 'center',

  originY: 'center'

});

var group = new fabric.Group([ circle, text ], {

  left: 150,

  top: 100,

  angle: -10

});

canvas.add(group);


组成组以后,依旧可以对每个对象操作,改变对象的属性和状态。

group.item(0).set('fill', 'red');

group.item(1).set({

  text: 'trololo',

  fill: 'white'

});


Serialization序列化

为构建某种有状态的应用程序,允许用户将canvas内容的结果保存在服务器上,或者将内容流媒体化到不同的客户端。Fabric.js提供了canvas序列化/解序列化支持。

toObject, toJSON

Fabric中序列化的主要方法是 fabric.Canvas#toObject()和 fabric.Canvas#toJSON()方法。让我们来看一个简单的例子,首先对一个空画布进行序列化。

var canvas = new fabric.Canvas('c');

JSON.stringify(canvas); // '{"objects":[], "background": "rgba(0,0,0,0,0)"}'


使用的是ES5 JSON.stringify()方法,如果传入的对象存在toJSON方法,那么这个方法就会隐含地调用toJSON方法。由于Fabric中的canvas实例有toJSON方法,所以调用JSON.stringify(canvas)方法和调用JSON.stringify(canvas.toJSON())一样。

注意,返回的字符串表示空的canvas。它是JSON格式的,本质上由 “objects”和”background”属性组成。”objects”目前是空的,因为canvas上没有任何东西,而 background 有一个默认的透明值(“rgba(0,0,0,0,0)”)。
当在canvas上添加了具体对象后:

canvas.add(new fabric.Circle({

  left: 100,

  top: 100,

  radius: 50,

  fill: 'red'

}));

console.log(JSON.stringify(canvas));


序列化后结果如下:

'{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,

"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,

"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red",

"overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,

"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}'


toSvg

Fabric.js支持将canvas画布序列化为SVG格式的文本。

canvas.add(new fabric.Rect({

  left: 50,

  top: 50,

  height: 20,

  width: 20,

  fill: 'green'

}));

console.log(canvas.toSVG());


序列化结果如下:

<?xml version="1.0" standalone="no" ?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve">

<desc>created with Fabric.js 0.9.21</desc>

<rect x="-10" y="-10" rx="0" ry="0" width="20" height="20" style="stroke: none; stroke-width: 1; stroke-dasharray: ; fill: green; opacity: 1;" transform="translate(50 50)" />

</svg>


Deserialization反序列化, SVG Parser SVG解析器

与序列化类似,反序列化是从字符串中加载canvas,与序列化时相对应的,也有两种方法:从JSON文本反序列和从SVG文本反序列化。当使用JSON表示时,有 fabric.Canvas#loadfromJSON和 fabric.Canvas#loadfromDatalessJSON方法。当使用SVG时,

有 fabric.loadSVGfromURL和 fabric.loadSVGfromString两个方法。

var canvas = new fabric.Canvas();

canvas.loadfromJSON('{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,

"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,

"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,

"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,

"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}');

下移:canvas.sendBackwards(obj)

上移:canvas.bringForward(obj)

置顶:canvas.bringToFront(obj)

置底:canvas.sendToBack(obj)

更多资源

fabric.js官网:http://fabricjs.com/
fabric.js源码:https://github.com/fabricjs/fabric.js
fabric.js应用案例:https://printio.ru/tees/new_v2
HTML5 Canvas资料:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial



该文章在 2023/5/23 11:21:46 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved