Fabric.js是一个能够简化Canvas程序编写的库。 Fabric.js为Canvas提供所缺乏的对象模型, svg parser, 交互和一整套其余不可或缺的工具。Fabric.js能够作不少事情,以下:ajax
npm 安装npm
npm install fabric --save
复制代码
cdn引用json
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>// 貌似国外相对较慢
复制代码
能够在https://www.bootcdn.cn/fabric.js/ 找到更快的CDN来源canvas
在使用前,先看下我作的整体效果以下:bash
建立了一个基本的画布框架
<canvas id="canvas" width="350" height="200"></canvas>
const card = new fabric.Canvas('canvas')
// ...这里能够写canvas对象的一些配置,后面将会介绍
// 若是<canvas>标签没设置宽高,能够经过js动态设置
card.setWidth(350)
card.setHeight(200)
复制代码
经常使用监听事件以下:svg
var canvas = new fabric.Canvas('canvas');
canvas.on('mouse:down', function(options) {
console.log(options.e.clientX, options.e.clientY)
})
复制代码
如下为经常使用的事件:工具
下面是原文,更多参考__fabricjs官网事件__:字体
So which other events are available in Fabric? Well, from mouse-level ones there are "mouse:down", "mouse:move", and "mouse:up". From generic ones, there are "after:render". Then there are selection-related events: "before:selection:cleared", "selection:created", "selection:cleared". And finally, object ones: "object:modified", "object:selected", "object:moving", "object:scaling", "object:rotating", "object:added", and "object:removed"动画
// 读取图片地址,设置画布背景
fabric.Image.fromURL('xx/xx/bg.jpg', (img) => {
img.set({
// 经过scale来设置图片大小,这里设置和画布同样大
scaleX: card.width / img.width,
scaleY: card.height / img.height,
});
// 设置背景
card.setBackgroundImage(img, card.renderAll.bind(card));
card.renderAll();
});
复制代码
fabric.js提供了不少对象,除了基本的 Rect,Circle,Line,Ellipse,Polygon,Polyline,Triangle对象外,还有如 Image,Textbox,Group等更高级的对象,这些都是继承自Fabric的Object对象。
/**
* 如何向画布添加一个Image对象?
*/
// 方式一(经过img元素添加)
const imgElement = document.getElementById('my-image');
const imgInstance = new fabric.Image(imgElement, {
left: 100, // 图片相对画布的左侧距离
top: 100, // 图片相对画布的顶部距离
angle: 30, // 图片旋转角度
opacity: 0.85, // 图片透明度
// 这里能够经过scaleX和scaleY来设置图片绘制后的大小,这里为原来大小的一半
scaleX: 0.5,
scaleY: 0.5
});
// 添加对象后, 以下图
card.add(imgInstance);
复制代码
/**
* 如何向画布添加一个Textbox对象?
*/
const textbox = new fabric.Textbox('这是一段文字', {
left: 50,
top: 50,
width: 150,
fontSize: 20, // 字体大小
fontWeight: 800, // 字体粗细
// fill: 'red', // 字体颜色
// fontStyle: 'italic', // 斜体
// fontFamily: 'Delicious', // 设置字体
// stroke: 'green', // 描边颜色
// strokeWidth: 3, // 描边宽度
hasControls: false,
borderColor: 'orange',
editingBorderColor: 'blue' // 点击文字进入编辑状态时的边框颜色
});
// 添加文字后,以下图
card.add(textbox);
复制代码
// 方式一
this.selectedObj = card.getActiveObject(); // 返回当前画布中被选中的图层
// 方式二
card.on('selection:created', (e) => {
// 选中图层事件触发时,动态更新赋值
this.selectedObj = e.target
})
复制代码
this.selectedObj.rotate(angle); //旋转图层 this.selectedObj.set({ scaleX: -this.selectedObj.scaleX, // 水平翻转 }) card.remove(this.selectedObj) // 传入须要移除的object this.selectedObj.bringForward();// 上移图层 this.selectedObj.sendBackwards();// 下移图层 card.moveTo(object, index);// 也可使用canvas对象的moveTo方法,移至图层到指定位置
// 全部图层的操做以后,都须要调用这个方法 card.renderAll()
主要是在添加图片对象的时候,有两个参数能够应用起来,分别是scaleX,scaleY参数,经过这两个参数,能够对应地缩放图片大小,方便图片能完整地在canvas画布体现出来。
先将手机图片加载完毕,算出宽和高,根据本身的画布纵横对比从新算出 图片的缩放参数便可。
new Promise(function(res,rej){
let img = new Image();
img.onload = function(){
console.log(img.width,img.height);
res([img.width,img.height]);
}
img.src = file.content;
}).then(function(response){
let width = response[0];
let height = response[1];
let xYRet = 0.61; //300/490 纵横对比
let targetRepix = 1;
if(height > 490)
{
targetRepix = (490/height).toFixed(2);
}
if(width > 300)
{
targetRepix = (300/width).toFixed(2);
}
fabric.Image.fromURL(file.content, (img) => {
img.set({
top:30,
left:30,
scaleX: targetRepix,
scaleY: targetRepix,
hasControls: true, // 是否开启图层的控件
borderColor: 'orange', // 图层控件边框的颜色
});
// 添加对象后, 以下图
card.add(img);
});
})
复制代码
//其中selectedObj 是当前选中的文字对象
this.selectedObj.set({
fontWeight:xxx //改变粗细
});
this.selectedObj.set({
fill:xxx //改变颜色
});
复制代码
card.on('selection:updated', (e) => {
console.log('selection:updated', e.target)
this.setSelectedObj(e.target)
//经过选中的对象更改样式
e.target.set({
transparentCorners: false,
cornerColor: 'blue',
cornerStrokeColor: 'red',
borderColor: 'red',
cornerSize: 12,
padding: 10,
cornerStyle: 'circle',
borderDashArray: [3, 3]
});
})
复制代码
效果以下图:
框架提供了如 toJSON 和 loadFromJSON 方法,做用分别为导出当前画布的json信息,加载json画布信息来还原画布状态。
// 导出当前画布信息
const currState = card.toJSON(); // 导出的Json以下图
// 加载画布信息
card.loadFromJSON(lastState, () => {
card.renderAll();
});
复制代码
const dataURL = card.toDataURL({
format: 'jpeg', // jpeg或png
quality: 0.8 // 图片质量,仅jpeg时可用
// 截取指定位置和大小
//left: 100,
//top: 100,
//width: 200,
//height: 200
});
复制代码