什么是Fabric.js

Fabric.js 是一个强大且简单的Javascript HTML5 Canvas库。

官网地址:http://fabricjs.com/

为什么要使用Fabric.js?

Canvas提供一个好的画布能力, 但是Api不够友好。绘制简单图形其实还可以, 不过做一些复杂的图形绘制, 编写一些复杂的效果,就不是那么方便了。Fabric.js就是为此而开发,它主要用对象的方式去编写代码。

Fabric.js能做的事情

  • 在Canvas上创建、填充图形(包括图片、文字、规则图形和复杂路径组成图形)。

  • 给图形填充渐变颜色。

  • 组合图形(包括组合图形、图形文字、图片等)。

  • 设置图形动画及用户交互。

  • 生成JSON、SVG数据等。

  • 生成Canvas对象自带拖拉拽功能。

它提供了灵活丰富的Api和可配置化参数轻松实现复杂的效果,该开源库已被许多开发者用于项目实践中,广受好评。

下载趋势图

项目开发实战

这里基于React框架为基础,介绍Fabric.js开发实战实例。

1、安装Fabric.js
npm install fabric --save
或
yarn add fabric
官网还支持按需模块定制构建,在你需要的特性模块前面勾选,然后一键构建。这样可以使得你整体的代码量减少。

2、引入Fabric.js
import {fabric} from 'fabric';
3、initCanvas 画布初始化
//创建画布
let canvasObj = new fabric.Canvas('snackCanvas');
//设置画布背景色
canvasObj.setBackgroundColor('#d5d5d5');
//设置画布宽度
canvasObj.setWidth(this.state.canvasWidth);
//设置画布高度
canvasObj.setHeight(this.state.canvasHeight);
//标识画布中元素选中时,是否还按原有的层级位置展示
canvasObj.preserveObjectStacking = true;/**
* 设置元素选中框的样式
*/
//边角节点背景透明 false
fabric.Object.prototype.transparentCorners = false;
//边角节点大小
fabric.Object.prototype.cornerSize = 6;
//边框颜色
fabric.Object.prototype.borderColor = 'rgba(83,152,248,1)';
//角节点内部颜色
fabric.Object.prototype.cornerColor = 'white';
//角节点边框颜色
fabric.Object.prototype.cornerStrokeColor = 'rgba(83,152,248,1)';/**
* 设置对象位置Left/Top的基准参考位置为自身中心点
* 默认 对象采用相对自身中心点旋转,即centeredRotation=true
*/
fabric.Object.prototype.originX = 'center';
fabric.Object.prototype.originY = 'center';this.editor = canvasObj;
4、画布事件监听
//元素点击选中事件处理
canvasObj.on('selection:created', function(options) {//console.log('selection:created');//console.log(options);if (options.target) {// TODO}
}//元素选中更新事件处理
canvasObj.on('selection:updated', function(options) {//console.log('selection:updated');//console.log(options);if (options.target) {// TODO}
}//元素取消选中事件处理
canvasObj.on('selection:cleared', function(options) {//console.log('selection:cleared');
}//对象移动完毕事件处理
canvasObj.on('object:moved', function(options) {//console.log('moved');//console.log(options);if (options.target) {}
}//对象旋转完成事件处理
canvasObj.on('object:rotated', function(options) {//console.log('rotated');//console.log(options);if (options.target) {// TODO}
}//对象缩放完成事件处理
canvasObj.on('object:scaled', function(options) {//console.log('scaled');//console.log(options);if (options.target) {}
}//对文本编辑修改后
canvasObj.on('text:changed', function(options) {//console.log('text:changed');//console.log(options);if (options.target) {}
}
5、画布拖拽事件处理
/**
* 拖拽事件处理 start
*/
document.addEventListener('dragstart', function(e){//拖拽图片,并传递对象if(e.target.className == 'img'){scope.mouseX = e.offsetX;scope.mouseY = e.offsetY;//拖拽数据let sourceStr = e.target.dataset.source;if(sourceStr){scope.dragData = JSON.parse(sourceStr);}scope.figureType = e.target.className;}
}, false);document.addEventListener('dragover', function(e){e.preventDefault();
}, false);//拖拽动作
this.dragObj('drop');dragObj(eventName){let scope = this;this.editor.on(eventName, function(opt){if((opt.e.target.className).trim() == 'upper-canvas' ){scope.dragEvt(eventName, opt);}});
}dragEvt(eventName, opt){let scope = this;if(eventName == 'dragover'){opt.e.preventDefault();}else if(eventName == 'drop'){//拖拽结束opt.e.preventDefault();//console.log(this.dragData);////对拖拽数据进行业务处理//}
}
/**
* 拖拽事件处理 end
*/
6、画布中的图片加载
const dragImageUrl = this.dragData.imageUrl;
fabric.Image.fromURL(dragImageUrl, function(image){image.set({id: getUUID(),left: imageLeft, top: imageTop,width: nodeWidth,height: nodeHeight,classname: 'img',source: scope.dragData,selectable,hasContorls}).scale(scope.state.canvasScale, scope.state.canvasScale).setCoords();//添加到画布scope.editor.add(image);//设置当前素材为选中状态scope.editor.setActiveObject(image);//重新渲染scope.editor.requestRenderAll();
});
7、画布中的字体库加载
//加载字体库数据, 默认load()方法 超时时长默认为3秒钟
loadAndUse(object, fontName, scope) {let myfont = new FontFaceObserver(fontName);myfont.load(null, 5000).then(function() {// when font is loaded, use it.if(object){object.source.fontFamily = fontName;object.set("fontFamily", fontName).setCoords();scope.editor.requestRenderAll();}}).catch(function(e) {console.log(e);alert('字体 ' + fontName + ' 加载失败。');});
}//字体方法的使用
this.loadAndUse(null, '宋体', this);
8、画布内容转换成图片保存到后台
saveData(){... 省略其他代码 ...let paramData = new FormData();let dataUrl = this.editor.toDataURL();let blobImage = this.dataURLtoBlob(dataUrl);blobImage.contentType = 'application/octet-stream';paramData.append("file", blobImage);... 省略其他代码 ...
}//数据类型转换
dataURLtoBlob(dataurl){let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);while(n--){u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], {type:'application/octet-stream'});
}
9、画布Canvas绘制的元素合并为一组

将两个元素深深地绑定在一起,任何操作同时对两个有效,这里叫组的概念

const circle = new fabric.Circle({radius: 100,fill: '#eef',scaleY: 0.5,originX: 'center',originY: 'center'
});const text = new fabric.Text('hello world', {fontSize: 30,originX: 'center',originY: 'center'
});const group = new fabric.Group([ circle, text ], {left: 150,top: 100,angle: -10
});
9、Canvas画布中将两个元素之间建立BOSS关系

怎么理解就是将一个元素变为另一个元素的boss,boss元素拖动旋转操作,另一个元素跟着同样变,但是反过来就不行

bindMinionToBoss(canvas: fabric.Canvas, boss: fabric.Group): void {const minions = canvas.getObjects().filter((o: any) => o !== boss);const bossTransform = boss.calcTransformMatrix();const invertedBossTransform = fabric.util.invertTransform(bossTransform);minions.forEach((o: any) => {const desiredTransform = fabric.util.multiplyTransformMatrices(invertedBossTransform,o.calcTransformMatrix());o.relationship = desiredTransform;});boss.on("moving", () => {minions.forEach((o: any) => {if (!o.relationship) return;const newTransform = fabric.util.multiplyTransformMatrices(boss.calcTransformMatrix(),o.relationship);const opt = fabric.util.qrDecompose(newTransform);const point = new fabric.Point(opt.translateX, opt.translateY);o.setPositionByOrigin(point, "center", "center");o.set(opt);o.setCoords();});});}

其他详细Api请参见:

http://fabricjs.com/docs/

另外还有很多好玩有趣的功能等着我们去发现,可以参照官网的例子:

http://fabricjs.com/demos/

如果使用中出现常见问题,优先参考:

http://fabricjs.com/fabric-gotchas

强大的Canvas开源库Fabric.js简介与开发指南相关推荐

  1. Canvas实用库Fabric.js使用手册

    简介 什么是Fabric.js? Fabric.js是一个可以简化Canvas程序编写的库. Fabric.js为Canvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的 ...

  2. HTML5 Canvas JavaScript库 Fabric.js 使用经验

    首先,表明我的态度:采用 Flash 才是最优方案,不建议使用 HTML 5 的 Canvas 做一些生产/工业级的网页应用. Flash的优势一是浏览器支持好,二是代码成熟稳定.而HTML5 的 C ...

  3. 27个iOS开源库,让你的开发坐上火箭吧

    本文翻译自Medium,原作者是Paweł Białecki,原文 27个iOS开源库,让你的开发坐上火箭吧 你不会想错过他们,真的. 我爱开源. 并且我喜欢开发者们,把他们宝贵的私人时间用来创造神奇 ...

  4. ios开发——27个iOS开源库,让你的开发坐上火箭吧

    本文翻译自Medium,原作者是Paweł Białecki,原文 27个iOS开源库,让你的开发坐上火箭吧 你不会想错过他们,真的. 我爱开源. 并且我喜欢开发者们,把他们宝贵的私人时间用来创造神奇 ...

  5. iOS开发——27个开源库,让你的开发坐上火箭吧

    27个iOS开源库,让你的开发坐上火箭吧 你不会想错过他们,真的. 我爱开源. 并且我喜欢开发者们,把他们宝贵的私人时间用来创造神奇的东西,然后他们会和其他人分享并且不求回报.开源作者和贡献者,你们是 ...

  6. js中的new file_深受 Pandas 启发的 JavaScript 开源库 — Danfo.js 现已推出!

    特邀博文 / 独立研究员 Rising Odegua 与来自 Data Science Nigeria 的 Stephen Oni Danfo.js 是个 JavaScript 开源库,提供了高性能. ...

  7. react-native 为本地js和开源库的js编写.d.ts声明文件

    读书不觉已春深 !明日清明节 在使用Typescript编写程序RN过程中遇到困扰,且不论react,不论在浏览器中,只论写react-native的APP,怎么使用 declare声明文件 和 na ...

  8. 【安卓开源集合】最全最有用的第三方开源库收集整理,快速开发必备,还能提升效率

    扩展功能库 SlidingMenu  : SlidingMenu 能非常容易的让开发者实现程序的抽屉效果,所谓的抽屉效果如下图所示,通常被用作呼出菜单.而且SlidingMenu能很方便的与Actio ...

  9. 针对Android平台播放器开源库NiceVieoPlayer倍速的开发

    Android平台的视频开源库可谓百花齐放,直接给出比较流行的几大框架github地址:https://github.com/search?l=Java&o=desc&q=ExoPla ...

最新文章

  1. GeforceRTX系列参数对比
  2. [物理学与PDEs]第2章习题13 将 $p$ - 方程组化为守恒律形式的一阶拟线性对称双曲组...
  3. 【数据库】Ubuntu12.04安装配置Redis3.0
  4. tableau必知必会之用参数操作实现数据下钻
  5. java barrier_Java并发类CyclicBarrier方法详解
  6. 关于lucene2.2部分代码
  7. fragment中嵌套viewpager,vierpager中有多个fragment,不显示 .
  8. 2021-2025年中国成人脊柱矫形器行业市场供需与战略研究报告
  9. 【洛谷 2863】牛的舞会
  10. 一个故事讲完CPU的工作原理 侵删
  11. 破14亿,用Python分析我国存在哪些人口危机!
  12. 三相短路电流计算机算法的原理什么,第三章电力系统三相短路电流及实用计算.ppt...
  13. python saveas_Python中正确的Save-As函数
  14. STM32显示图片,将图片转换为十六进制数组便捷工具
  15. Sorted Adjacent Differences
  16. ubuntu将电源键设置为关机
  17. php英语大全,php常用英语单词-音标版
  18. 深入剖解路由器的“心脏”技术
  19. Qt编写安防视频监控系统10-视频轮询
  20. 微信公众号开发,报错{errcode:41005,errmsg:media data missing hint:}的解决办法---亲测有效

热门文章

  1. 工业以太网在工业领域的应用特点详解
  2. 【渝粤教育】国家开放大学2018年春季 0463-22T英语语音 参考试题
  3. 【渝粤题库】陕西师范大学152102 管理学原理作业(高起专)
  4. mysql内表和外表_Hive内表和外表的区别
  5. oracle 中文脚本,ORACLE常用脚本
  6. lda进行图片分类_LDA主题模型
  7. 英语作文计算机主板,(完整版)电脑主板bios英文版的中英文对照翻译.pdf
  8. php json追加500错误,在composer.json中添加了一个git地址;composer update 报错
  9. elasticsearch和php,快速开始 | Elasticsearch-PHP | Elastic
  10. python人工智能入门优达视频_机器学习:优达教你搭建Python 环境的正确姿势