簡介什么是Fabric.js?
Fabric.js是一個可以簡化Canvas程序編寫的庫。 Fabric.js為Canvas提供所缺少的對象模型, svg parser, 交互和一整套其他不可或缺的工具。由於Fabric.js為國外框架,官方API雜亂繁多,相關文檔大多為英文文檔,而且數量不多,所以本文旨在幫助新手在項目中快速上手Fabric.js,享受繪制Canvas的過程。
為什么要使用Fabric.js?
Canvas提供一個好的畫布能力, 但是Api不夠友好。繪制簡單圖形其實還可以, 不過做一些復雜的圖形繪制, 編寫一些復雜的效果,就不是那么方便了。Fabric.js就是為此而開發,它主要就是用對象的方式去編寫代碼。
Fabric.js能做的事情
- 在Canvas上創建、填充圖形(包括圖片、文字、規則圖形和復雜路徑組成圖形)。
- 給圖形填充漸變顏色。
- 組合圖形(包括組合圖形、圖形文字、圖片等)。
- 設置圖形動畫集用戶交互。
- 生成JSON, SVG數據等。
- 生成Canvas對象自帶拖拉拽功能。
起步
Vue項目中引入Fabric.js
假設您的項目中正在使用ES6和Webpack,您可以開始使用Fabric.js,如下所示:
1、在命令行中:
1
|
npm
install
fabric(或yarn add fabric)
|
2、將其引入 .vue
文件中
1
|
import { fabric } from
'fabric'
|
3、在 .vue
的單文件中的 mounted:
生命周期里開始你的Fabric.js之旅啦
注:默認的fabric npm模塊產生了相當大的包,如果Fabric.js中您有很多可能不需要的包,在這種情況下,可以在 在此處 或在命令行中構建你自己的版本。
繪制圖形
繪制規則圖形
1、聲明畫布
1
|
var
canvas =
new
fabric.Canvas(
'main'
);
|
2、繪制圖形
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var
rect =
new
fabric.Rect({
left:100,
//距離畫布左側的距離,單位是像素
top:100,
//距離畫布上邊的距離
fill:
'red'
,
//填充的顏色
width:30,
//方形的寬度
height:30
//方形的高度
});
|
3、添加圖形至畫布
1
|
canvas.add(rect);
|
Fabric提供了7中基本的對象類,如果只是單純的畫這些圖形的話,會節省我們很多的時間:
- fabric.Circle //圓形
- fabric.Ellipse //橢圓
- fabric.Line //線
- fabric.Polygon //多邊形
- fabric.Polyline //交叉線 折線
- fabric.Rect //矩形
- fabric.Triangle//三角形
這些實例都繼承fabric.Object,如果你想畫一些圖形,並且需要一些公共方法。這時候你就可以在fabric.Object上定義一個方法,來讓子類繼續。
比如我們定一個方法getAngleInRadians 方法在fabric.Object對象上:
fabric.Object.prototype.getAngleInRadians = function() { return this.get('angle') / 180 * Math.PI; }; var rect = new fabric.Rect({ angle: 45 }); rect.getAngleInRadians(); // 0.785... var circle = new fabric.Circle({ angle: 30, radius: 10 }); circle.getAngleInRadians(); // 0.523... circle instanceof fabric.Circle; // true circle instanceof fabric.Object; // true
繪制不規則圖形
使用路徑繪圖:用點和線的移動的方式進行繪圖。通過對 線、曲線、弧的應用繪制非常復雜的圖形。
在fabric.Path( )方法中,“M”代表“移動”命令,這個“M 00” 代表把畫筆移動到(0,0)點坐標。
“L”代表“線”,“L 200 100 ”的意思是使用鋼筆畫一條線,從(0,0)坐標畫到(200,100)坐標。 “z” 代表讓圖形閉合路徑。
畫好三角形后,我們可以用set( )方法對三角形的位置、顏色、角度、透明度等屬性進行設置。
具體代碼如下:
1
2
3
|
var
path =
new
fabric.Path(
'M 0 0 L 200 100 L 170 200 z'
);
path.set({ left: 120, top: 120,fill:
'red'
});
canvas.add(path);
|
對圖片的操作
HTML插入圖片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
body
>
<
canvas
id
=
"canvas"
width
=
'800'
height
=
'800'
></
canvas
>
<
img
src
=
"./2.png"
id
=
"img"
>
</
body
>
---------------------
var canvas = new fabric.Canvas('canvas');//聲明畫布
var imgElement = document.getElementById('img');//聲明我們的圖片
var imgInstance = new fabric.Image(imgElement,{ //設置圖片位置和樣子
left:100,
top:100,
width:200,
height:100,
angle:30//設置圖形順時針旋轉角度
});
canvas.add(imgInstance);//加入到canvas中
|
JavaScript插入圖片
1
2
3
4
5
|
var
canvas =
new
fabric.Canvas(
'canvas'
);
fabric.Image.fromURL(
'./2.png'
,
function
(oImg) {
oImg.scale(0.1);
//圖片縮小10倍
canvas.add(oImg);
});
|
交互
對畫布的交互
1
2
3
4
5
|
canvas.add(imgInstance);
//加入到canvas中
var
canvas =
new
fabric.Canvas(
'canvas'
);
canvas.on(
'mouse:down'
,
function
(options) {
console.log(options.e.clientX, options.e.clientY)
})
|
注:常用監聽事件如下:
mouse:down
:鼠標按下時mouse:move
:鼠標移動時mouse:up
:鼠標抬起時
對畫布上對象的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var
canvas =
new
fabric.Canvas(
'canvas'
);
var
rect =
new
fabric.Rect({ width: 100, height: 50, fill:
'green'
});
rect.on(
'selected'
,
function
() {
//選中監聽事件
console.log(
'selected a rectangle'
);
});
var
circle =
new
fabric.Circle({ radius: 75, fill:
'blue'
});
circle.on(
'selected'
,
function
() {
console.log(
'selected a circle'
);
});
canvas.add(rect);
canvas.add(circle);
|
注:常用監聽事件如下:
after:render
:畫布重繪后object:selected
:對象被選中object:moving
:對象移動object:rotating
:對象被旋轉object:added
:對象被加入object:removed
:對象被移除
組合
new fabric.Group():接受兩個參數:要組合對象名稱組成的數組、組合到一起的對象的共同屬性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
var
canvas =
new
fabric.Canvas(
'canvas'
);
var
circle =
new
fabric.Circle({
//繪制圓形
radius: 100,
fill:
'#f00'
,
scaleY: 0.5,
originX:
'center'
,
//調整中心點的X軸坐標
originY:
'center'
//調整中心點的Y軸坐標
});
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);
|
序列化與反序列化
序列化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var
canvas =
new
fabric.Canvas(
'canvas'
);
var
rect =
new
fabric.Rect({
width: 100,
height: 100,
fill:
'red'
});
canvas.add(rect);
console.log(JSON.stringify(canvas.toJSON()));
|
反序列化
1
2
3
|
var
canvas =
new
fabric.Canvas(
'canvas'
);
canvas.loadFromJSON(
'{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null}'
)
|
SVG
1
2
3
4
5
6
7
8
9
10
11
|
var
canvas =
new
fabric.Canvas(
'canvas'
);
var
rect =
new
fabric.Rect({
width: 100,
height: 100,
fill:
'red'
});
canvas.add(rect);
canvas.toSVG();
|
fabric.js使用筆記
對象
fabric.Circle 圓
fabric.Ellipse 橢圓
fabric.Line 直線
fabric.Polygon
fabric.Polyline
fabric.Rect 矩形
fabric.Triangle 三角形
方法
add(object) 添加
insertAt(object,index) 添加
remove(object) 移除
forEachObject 循環遍歷
getObjects() 獲取所有對象
item(int) 獲取子項
isEmpty() 判斷是否空畫板
size() 畫板元素個數
contains(object) 查詢是否包含某個元素
fabric.util.cos
fabric.util.sin
fabric.util.drawDashedLine 繪制虛線
getWidth() setWidth()
getHeight()
clear() 清空
renderAll() 重繪
requestRenderAll() 請求重新渲染
rendercanvas() 重繪畫板
getCenter().top/left 獲取中心坐標
toDatalessJSON() 畫板信息序列化成最小的json
toJSON() 畫板信息序列化成json
moveTo(object,index) 移動
dispose() 釋放
setCursor() 設置手勢圖標
getSelectionContext()獲取選中的context
getSelectionElement()獲取選中的元素
getActiveObject() 獲取選中的對象
getActiveObjects() 獲取選中的多個對象
discardActiveObject()取消當前選中對象
isType() 圖片的類型
setColor(color) = canvas.set("full","");
rotate() 設置旋轉角度
setCoords() 設置坐標
事件
object:added
object:removed
object:modified
object:rotating
object:scaling
object:moving
object:selected 這個方法v2已經廢棄,使用selection:created替代,多選不會觸發
before:selection:cleared
selection:cleared
selection:updated
selection:created
path:created
mouse:down
mouse:move
mouse:up
mouse:over
mouse:out
mouse:dblclick
常用屬性
canvas.isDrawingMode = true; 可以自由繪制
canvas.selectable = false; 控件不能被選擇,不會被操作
canvas.selection = true; 畫板顯示選中
canvas.skipTargetFind = true; 整個畫板元素不能被選中
canvas.freeDrawingBrush.color = "#E34F51" 設置自由繪畫筆的顏色
freeDrawingBrush.width 自由繪筆觸寬度
canvas.setZoom(2); 設置畫板縮放比例
IText的方法
selectAll() 選擇全部
getSelectedText() 獲取選中的文本
exitEditing() 退出編輯模式
繪制直線
var line = new fabric.Line([10, 10, 100, 100], {
fill: 'green',
stroke: 'green', //筆觸顏色
strokeWidth: 2,//筆觸寬度
});
canvas.add(line);
繪制虛線
在繪制直線的基礎上添加屬性strokeDashArray:Array
example:
var line = new fabric.Line([10, 10, 100, 100], {
fill: 'green',
stroke: 'green',
strokeDashArray:[3,1]
});
canvas.add(line);
strokeDashArray[a,b] =》 每隔a個像素空b個像素。
可繪制對象
fabric.Circle 圓
fabric.Ellipse 橢圓
fabric.Line 直線
fabric.Polygon
fabric.Polyline
fabric.Rect 矩形
fabric.Triangle 三角形
圖片去掉選中邊框和旋轉,且只能移動,不可操作
oImg.hasControls = false; 只能移動不能(編輯)操作
oImg.hasBorders = false; 去掉邊框,可以正常操作
hasRotatingPoint = false; 不能被旋轉
hasRotatingPoint 控制旋轉點不可見
scaleToHeight(value, absolute) 縮放圖片高度到value scaleToWidth(value, absolute) 縮放圖片寬度到value
示例代碼如下:
fabric.Image.fromURL("img.jpg", function (oImg) { img.scaleToHeight(400, false); //縮放圖片的高度到400 img.scaleToWidth(400, false); //縮放圖片的寬度到400 canvas.add(oImg); oImg.hasControls = oImg.hasBorders = false; });