fabricjs
在国内并不算特别出名,但是在国外应该是特别的火了。它是一个强大的js库,使用它能够很方便的操作canvas。平时使用canvas的时候,总要学习它的各个api,画简单图形还算熟练,一旦稍微复杂一点就需要不断的查文档,非常不方便。fabric.js提供在上面建立元素、编辑图形和文本、对svg和json格式的序列化和反序列化、对元素进行事件响应等等功能。fabricjs是一个完全开源的项目,由麻省理工学院授权,多年来一直发光发热。
npm install fabric
<script src ="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js" > </script >
html的body中存在一个如下的canvas元素,获取这个元素fabric对象:var canvas = new fabric.Canvas( 'main' )
;
<canvas width="800" height="800" id="main" ></canvas>
在canvas上画矩形:
var rect = new fabric .Rect ({
left : 100 ,
top : 100 ,
fill : '#f0f' ,
width : 30 ,
height : 30
canvas .add (rect);
如果使用原生canvas api创建矩形,则会是:
var ele = document.getElementById('main' )
var ctx = canvasEl.getContext('2d' )
ctx.fillStyle = '#f0f'
ctx.fillRect(100, 100, 30, 30)
虽然代码量差不多,但是fabric可以是的图形对象化,在之后还可以继续操作这个对象,如果想要获取rect的属性,只需要 rect.get('')
,或者想要添加其他的属性,可以使用 rect.set
,如果想要从canvas上删除这个rect,只需要 canvas.remove(rect)
。
在canvas上画圆形:
var circle = new fabric.Circle ({
radius : 50 ,
fill : "#fcb" ,
left : 200 ,
top : 100 ,
在canvas上画三角形:
var trigle = new fabric.Triangle ({
fill : "#fcb" ,
left : 300 ,
top : 100 ,
height : 100 ,
width : 80 ,
如果页面中存在img元素: <img src="./d2.png" id="img-d2" style="display: none;">
,那么要将这个元素加载到canvas中:
var imgEle = document .getElementById ('img-d2' );
var imgInstance = new fabric .Image (imgEle, {
left : 100 ,
top : 100 ,
width : 200 ,
height : 200 ,
angle : 30
canvas .add (imgInstance);
这个img元素如果是用于显示在页面中还好,如果只是为了给fabric添加图片素材,加一个这样的img元素会显得有点多余。fabric还提供了根据url创建图片对象的方法:
fabric .Image .fromURL ('./d2.png' , function (img){
console .log (img);
canvas .add (img);
left : 100 ,
top : 100 ,
width : 200 ,
height : 200 ,
angle : 30
创建图片之后也可以对图片对象进行操作,平常我们使用图片用于背景或者突出一个显示效果,那么可以这么使用:
canvas .setBackgroundImage ('./d2.png ', canvas .renderAll .bind (canvas ));
也可以多个图片叠加使用作为背景图,在上面代码的基础上设置:
canvas .setOverlayImage ('../assets/d1.png ', canvas .renderAll .bind (canvas ));
显示效果:
对图片进行添加滤镜:
img .filters .push (new fabric.Image.filters.Grayscale (), new fabric.Image.filters.Invert ());
img .applyFilters (img.filters);
滤镜效果图
更多的滤镜效果可以通过查文档获得,至于图片对象的缩放、旋转之类的效果可以通过设置它的属性获得,比如设置旋转60度 img.set('angle', 60)
。
不规则图形
在canvas上画不规则图形:
var path = new fabric.Path ('M 0 0 L 200 100 L 170 200 z' );
path.set ({
left : 120 ,
top : 120 ,
fill : "#4040fe"
对于在canvas上画不规则路径或者图形,“M”表示“move”命令,在这个例子中意味着从 0,0
始。“L”代表“直线”,让钢笔画一条直线到 200,100
。另一个“L”创建一条到 177,200
的线
“z”指示绘图笔关闭当前路径并最终确定形状。同样它也可使用set来设置它的其他属性,达到更多的效果:path.set({ fill: 'red', stroke: 'green', opacity: 0.5 });
除了上面的M、L之类还可以用C,C表示贝赛尔曲线,它的作用是画出曲线, var
path = new fabric.Path('M 0 0 L 200 100 L 170 200 C36.67,0,29.5,3.22,24.31,8.41 Z');
但是使用自己去设置点,得到想要的不规则是非常困难的。fabric提供了加载svg来代替这种方式进行实现, loadSVGFromString
或者 loadSVGFromURL
方法来加载SVG文件,让Fabric的SVG解析器来遍历所有SVG元素并创建相应的Path对象。
fabric.loadSVGFromURL ('./tab.svg', function(objects){
var SVG = fabric.util .groupSVGElements (objects);
canvas .add (SVG).centerObject (SVG).renderAll ();
SVG.setCoords ();
fabric提供了很方便的方式创建颜色,这些颜色都可以创建的图形中去:
var col1 = new fabric.Color('#f55' )
var col2 = new fabric.Color('#123123' )
var col3 = new fabric.Color('356735' )
var col4 = new fabric.Color('rgb(100,0,100)' )
var col5 = new fabric.Color('rgba(10, 20, 30, 0.5)' )
rgb和hex色值可以相互进行转换:
col1.to Rgb ()
col4.to Hex ()
颜色变换:
覆盖: var colo5 =
col2 .overlayWith(
col3 );
如果col2进行了这个操作,不仅会得到一个新的颜色col5,col2也会被覆盖。
转换: col2.toGrayscale()
转换成灰度图颜色,其他变换可以查api得到。
颜色应用:
new fabric .Rect ({
left : 100 ,
top : 100 ,
width : 100 ,
height : 100 ,
fill : col2.toRgb ()
rect .setGradient ('fill' ,{
x1: 0,
y1: 0,
x2: circle.width,
y2 : 0 ,
colorStops :{
0 : col1.toRgb (),
1 : col3.roRgb ()
对于图形对象的属性,通过 set
进行设置,如果想要将这个属性设置动画效果,类似css中的transition,可以指定属性进行设置。
rect.animate ('left' , "500" , {
onChange: canvas.renderAll.bind (canvas),
duration: 2000 ,
easing: fabric.util.ease.easeInOutBounce
不想计算动画最终的数值,你可以使用 +=``-=
计算符号
rect.animate ('left' , "+=500" , {
onChange: canvas.renderAll.bind (canvas),
duration: 2000 ,
easing: fabric.util.ease.easeInOutBounce
animate函数的第三个参数中常用的属性有:
from
:允许指定动画属性的起始值(如果我们不希望使用当前值)。
duration
:动画持续时间
onComplete
:完成时的回调函数
onChange
:数值变化时调用的函数
easing
:动画变化的曲线
fabric不仅以对象的形式操作文本,还提供了比canvas操作文本 更多的功能 :
支持多行输入、文字对齐方式选择、文字背景设置、文本修饰、文本行高、设置字间距、修改样式、富文本(支持标签)、在 canvas
进行输入编辑。
常用的创建文本的方法有下面两种,它们的参数:第一个参数是文本内容,第二个则是文本的属性对象
var txt = new fabric .Text ('aker' , {
left : 140 ,
top : 140 ,
shadow : 'rgba(0,0,0,0.3) 15px 15px 15px' ,
fontFamily : 'Hoefler Text' ,
stroke : '#ff1318' ,
strokeWidth : 2 ,
fill : '#0f0' ,
fontSize : 60 ,
var tex = new fabric .IText ('click' ,{left :100 ,top :400 , minWidth : 50 });
对于文本的操作属性和css中的属性特别类似,还可以对文本进行背景色等等设置。常用的属性除了上面几个,还有: fontWeight、textDecoration、fontStyle、textAlign、textBackgroundColor、lineHeight
等等
前面讲的都是对单个元素的创建以及操作,fabric也提供了将创建的对象进行组合的方法 group
,将几个对象进行组合成为一个新的对象之后进行操作:
var canvas = new fabric.Canvas ('main' );
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的中心点进行放置对象,如果需要设置对象在组合中的位置,可以在创建对象的时候设置位置,如:
var circle3 = new fabric.Circle ({
radius : 50 ,
fill : 'blue' ,
left : 200
group可以看作是一个小型的canvas,因为它和canvas操作对象很类似。在创建完group之后,可以对添加的对象进行操作:
group .item(0 ).set ('fill' , 'red' );
group .item(1 ).set ({
text: 'trololo' ,
fill: 'white'
常用的操作items方法还有: size()
表示组中所有对象的数量。 contains()
允许检查特定对象是否在组中, add
添加对象, remove
移除对象, addWithUpdate
组的中心添加对象并更新组的属性。
fabric不仅提供了创建了对象的方法,也提供对创建的对象进行事件监听的方法。在fabric官网中也给出了对鼠标移动事件的demo。fabric事件监听类似jq里面对事件的处理。下面是fabric对鼠标点击事件监听demo:
var canvas = new fabric .Canvas ('main' );
canvas .on ('mouse:down' , function (options) {
console .log (options.e.clientX, options.e.clientY);
if (options.target) {
console .log ('an object was clicked! ' , options.target.type);
var rect = new fabric .Rect ({
left : 100 ,
top : 100 ,
fill : '#f0f' ,
width : 30 ,
height : 30
canvas .add (rect);
fabric提供的事件比较少,不过相对于自己用原生去写肯定方便很多,提供的事件有:
鼠标响应事件:"mouse:down", "mouse:move",和 "mouse:up".
一般性事件:"after:render"
选择事件:"before:selection:cleared", "selection:created", "selection:cleared".
对象事件:"object:modified", "object:selected", "object:moving", "object:scaling", "object:rotating", "object:added", and "object:removed"
官方文档上对于object:moving"和"object:scaling有特别备注,这两个事件特别灵敏,哪怕只是1px的变化也会产生响应,所以如果使用这两个事件的话,需要添加防抖。使用好这些事件应该可以满足许多的场景,比如画布的保存,可以对 object:modified
进行监听,如果发生了就存储,那么可以避免修改丢失。
前三种事件都是在画布上面,对于事件对象可以通过options参数获得,后面的对象事件也可以用于图层对象,加入创建了rect对象,监听选中时间:
rect.on ('selected' , function () {
console .log ('selected a rectangle' );
我的实验结果是这样的,上面的对象on事件的时候并没有反应(也许是使用问题)。
对于一个应用程序,如果只是提供在上面进行操作的方法并不够,要不然就会成为一个纯展示用的应用,还需要提供一个能够保存数据或者提取数据的方法。fabric提供了很好的序列化和反序列化方法,可以保存数据为json、base64的图片、svg、对象object、字符串toString。
var canvas = new fabric.Canvas ('main ');
console.log (canvas .toString ())
对于所有的画布对象都有toString方法,我们自己也可以创建对象进行toString覆盖。
对于toString只能得到简单的输出结果,并不能直观获取到对象详细信息,我们可以使用toObject或者toJson(这两个类似):
console.log (rect.toObject ())
console.log (rect.toJSON ())
console.log (rect.toString ())
输出结果如下,展开结果可以看到对于没设置的属性会默认给0或者null。
对于反序列化需要注意的是loadFromJSON对应toJSON、loadFormDatalessJSON对应toDatalessJSON。但是由于性能考虑,不是所有属性都可以进行序列化, fabric
只是包装了一些常用的属性,所以如果设置了一些比较少用的属性,在加载JSON数据的时候需要重新修改图像的属性。更多关于序列化可以查看 文档 。
图片编辑器
fabricjs.com/articles/
www.321332211.com/thread?topi…
注:随便写的一些 demo ,有兴趣的玩一下
3849
Sugars
Canvas
JavaScript
3168
PILIPALAPENG
JavaScript
Canvas
2073
zhuyujin001
Photoshop
本系统是基于fabric.js实现的canvas版图片,文本编辑器,支持对图片的放大,缩小,旋转,镜面翻转,拖动,显示/隐藏图层,删除图层,替换图层等操作,对文本支持修改文本内容,颜色,字体,加粗,斜体,下划线,背景色等,同时支持图片已有的操作,拖动图层有辅助线功能,可对画布做…