狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

Fabric.js介紹

admin
2023年5月23日 10:1 本文熱度 1536

Fabric.js是什么

Fabric.js 是一個簡化HTML5 Canvas開發(fā)的Javascript庫,F(xiàn)abric.js提供了HTML5 Canvas本身缺失的對象模型、交互層、SVG解析器以及其他一整套工具。它是一個完全開源的項目,在MIT下獲得授權(quán),多年來一直在維護(hù),近期要發(fā)布4.0版本,支持自定義controls。

Fabric.js能做什么

在Canvas畫布上創(chuàng)建、填充圖形(包括圖片、文字、規(guī)則圖形和復(fù)雜路徑組成圖形)。
給圖形填充漸變顏色。
組合圖形(包括組合圖形、圖形文字、圖片等)。
設(shè)置圖形動畫及用戶交互,生成的對象自帶拖拉拽功能。
JSON, SVG數(shù)據(jù)的序列化和反序列化。

為什么使用Fabric.js

HTML5 Canvas提供了完整的畫布,可以輕松的在畫布上繪制簡單的圖形、制作簡單的動畫,但是HTML5 Canvas提供的API過于低級,且操作基于上下文,因此在繪制復(fù)雜圖形或者需要實現(xiàn)用戶交互時,就顯得不是那么方便了。Fabric.js在HTML5 Canvas原生API之上,提供完整的對象模型,由Fabric.js來管理HTML5 Canvas畫布的狀態(tài)和渲染,用戶基于具體的對象,來編寫代碼,完成所需功能的開發(fā)(類似于面向過程和面向?qū)ο螅!癟alk is cheap. Show me the code”,下面通過代碼來看看用HTML5 Canvas原生方法和用Fabric.js分別實現(xiàn)在畫布上畫一個矩形這一功能。

用HTML5 Canvas的原生方法實現(xiàn)

// 獲取canvas元素

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

// 獲取上下文

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

// 設(shè)置填充顏色

ctx.fillStyle = 'red';

// 在100,100點創(chuàng)建20x20的矩形

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

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

用Fabric.js實現(xiàn)相同的功能:

// 創(chuàng)建原生canvas元素的包裝類(‘c’canvas元素的id)

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

// 創(chuàng)建一個矩形對象

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(代表整個畫布位圖的對象)進(jìn)行操作,而使用Fabric.js,我們是對對象操作,只需要去實例化對象,設(shè)置對象的屬性,然后將它們添加到canvas中。到這里,可能還感受不到Fabric對比原生Canvas方法的優(yōu)勢,下面可以完成這樣的功能,即在剛才繪制的矩形的基礎(chǔ)上,將矩形位置移動到(10,10)點上。
這樣的功能,在Canvas原生方法上實現(xiàn),需要先把原來的矩形從畫布上清除,然后在(10,10)位置重新繪制一個矩形,以此來實現(xiàn)矩形移動這樣的功能。

// 擦除之前的矩形(這里是擦除了整個canvas區(qū)域)

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

// 重新繪制矩形

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

聽起來是不是很蹩腳?是的,使用Canvas原生方法時,就像是個帶橡皮檫的筆刷,在畫布上繪制圖形時,是筆刷在畫布上移動,繪制出的圖形就是筆刷移動的整個痕跡,而想把繪制好的圖形移動到其他地方,只好用橡皮檫擦掉,然后在新位置重新繪制。

相應(yīng)的,使用Fabric.js實現(xiàn)該功能時,只需要改變矩形對象的屬性,然后重新刷新(渲染)畫布即可。

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

canvas.renderAll();


Canvas對象

fabric.Canvas作為元素的包裝器,創(chuàng)建fabric.Canvas對象如下:

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


它接收一個元素的id,并返回一個fabric.Canvas 的實例。fabric.Canvas對象,并不是DOM里的元素,如果需要直接控制DOM,或者對應(yīng)的context,需要通過相應(yīng)API去獲取。

var canvasElement = document.getElementById(canvasEle);

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

fabric.Canvas對象負(fù)責(zé)管理畫布上繪制的所有對象,可以將對象添加到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對象可以對畫布進(jìn)行配置。比如需要為整個畫布設(shè)置背景顏色或圖像?需要將所有內(nèi)容剪裁到特定區(qū)域?設(shè)置不同的寬度/高度?指定畫布是否是交互式的?所有這些選項(及其他)都可以在fabric.Canvas對象上進(jìn)行設(shè)置,可以在創(chuàng)建時或之后進(jìn)行設(shè)置。

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(){ /* ...... */ };

// ...


注意這種創(chuàng)建對象的形式,F(xiàn)abric.js里基本上都是類似的,類名表示要創(chuàng)建的對象類型,第一個參數(shù)是必要的數(shù)據(jù),第二個參數(shù)是各種選項。

所有對canvas的修改,包括在其中添加刪除對象,以及對象參數(shù)的修改,都需要調(diào)用渲染方法才能顯示出來:

canvas.renderAll();


Objects基本圖形
Fabric.js提供了7種基本圖形,下面是圖形對應(yīng)的類:

fabric.Circle

fabric.Ellipse

fabric.Line

fabric.Polygon

fabric.Polyline

fabric.Rect

fabric.Triangle


所有基本形狀,都可以通過類實例的屬性頭椒ɡ純刂撲塹奈恢謾⒀丈⒋笮〉妊健K欣嘍技壇兇詅abric.Object類,有一些公共的屬性和方法。

創(chuàng)建

下面是畫線的例子(給出兩個頂點坐標(biāo)):

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),應(yīng)該是借用了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);


從這里可以看出,和創(chuàng)建canvas類似,第一個參數(shù)是這個類專用的(比如畫直線的時候傳的起止點坐標(biāo)),第二個參數(shù)是通用選項,如果沒有專用參數(shù),那么第一個參數(shù)就直接是通用選項。所有創(chuàng)建完的形狀,只有通過canvas.add方法加入,才能顯示出來。

控制

left和top是每種Object都有的屬性,至于它到底指圖形中哪一個點的坐標(biāo),由originX和originY這組參數(shù)決定,它們相當(dāng)于文本編輯軟件里的對齊方式,originX有三種可選值:left,center, right;originY也有三種可選值:top, center, bottom。

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

如果希望對象的默認(rèn)原點在中心,可以這樣設(shè)置:

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的子類,最大的區(qū)別在于,圖像文件的加載是異步的,所以對Image的后續(xù)操作,都要在回調(diào)中完成。

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由一系列的命令組成,本質(zhì)上是模仿一支筆從一個點到另一個點。在“move”, “l(fā)ine”, “curve”, or “arc”等命令的幫助下,Path可以形成非常復(fù)雜的形狀。而在Paths(PathGroup’s)組的幫助下,Path的能實現(xiàn)更多的復(fù)雜圖形。
Fabric.js中的Path與SVG的 元素非常相似。它們使用相同的命令集,可以從 元素中創(chuàng)建,并將其序列化。我們稍后會更深入地研究序列化和SVG解析,但現(xiàn)在值得一提的是,實踐中很少會手動創(chuàng)建Path實例。相反,更多的是使用Fabric.js的內(nèi)置SVG解析器。
手工創(chuàng)建一個簡單的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 “告訴畫筆關(guān)閉當(dāng)前路徑并最終確定形狀。結(jié)果,得到的是一個三角形的形狀。

由于 fabric.Path 就像 Fabric 中的其他對象一樣,我們還可以改變它的一些屬性。但我們還可以對它進(jìn)行更多的修改。

...

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 元素的解析工作,并創(chuàng)建相應(yīng)的 Path 對象。

Events事件

事件驅(qū)動的架構(gòu)是一個框架靈活性和可擴(kuò)展性的基礎(chǔ)。Fabric.js提供了一個廣泛的事件系統(tǒng),覆蓋了低級的 “鼠標(biāo)”事件到高級的對象事件。
這些事件使我們能夠監(jiān)控到到畫布上發(fā)生的各種動作的不同時刻。比如想知道鼠標(biāo)被按下的時間,只需監(jiān)聽”mouse:down”事件就可以了。想知道對象何時被添加到畫布上,只需要監(jiān)聽”object:added “事件就在那里。

事件API非常簡單,類似于jQuery、Underscore.js或其他流行的JS庫。有on方法來初始化事件監(jiān)聽器,有off方法來移除事件監(jiān)聽器。

下面一個實際的例子。

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

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

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

});


上面例子演示了在canvas上添加”mouse:down”事件監(jiān)聽器,并給它設(shè)置事件處理程序,它將記錄事件發(fā)生的坐標(biāo)。事件處理程序會接收一個選項對象,它有兩個屬性:e—原始事件,和target—畫布上的點擊對象(如果有的話)。該事件在任何時候都是存在的,但目標(biāo)只有在實際點擊了畫布上的某個對象后才會存在。target也只有在有意義的情況下才會傳遞給事件的處理程序,例如,對于 “mouse:down”事件,但對于 “after:render”事件(表示整個畫布被重新繪制),target不會傳遞給事件處理程序。

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

  if (options.target) {

    console.log('一個對象被點擊了!', options.target.type);

  }

});


如果你點擊了一個對象,上面的例子會輸出 “一個對象被點擊了!”。還會顯示被點擊的對象類型。

那么,在Fabric.js中還有鼠標(biāo)級的事件:“mouse:down”, “mouse:move”, 和”mouse:up”。通用的事件: “after:render”。選擇相關(guān)的事件: “before:selection:cleared”,”selection:create”,”selection:cleared”。對象相關(guān)的事件: “object:moded”、”object:selected”、”object:moving”、”object:scaling”、”object:rotating”、”object:additional “和 “object:detter”。
注意,像”object:moving”(或”object:scaling”)這樣的事件在每次對象移動(或縮放)時,即使是一個像素點的移動,也會連續(xù)地被觸發(fā)。另一方面,像 “object:modified” 或 “selection:create”這樣的事件只在操作(對象修改或選區(qū)創(chuàng)建)結(jié)束時才會被觸發(fā)。如果將事件直接附加到畫布上的(canvas.on(‘mouse:down’, …)),這意味著事件被覆蓋到了canvas實例上。如果一個頁面上有多個畫布,可以給每個畫布附加不同的事件監(jiān)聽器。它們都是獨立互不影響的。
為了方便,F(xiàn)abric.js將事件系統(tǒng)做得更進(jìn)一步,允許直接將監(jiān)聽器附加到具體對象上。如下例子。

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('選擇了一個圓圈');

});


上述例子直接給矩形和圓的實例附加事件監(jiān)聽器,使用的是 “selected “事件,而不是 “object:selected”。同樣的,可以在對象上使用 “modified”事件(當(dāng)附加到canvas上時使用 “object:modified”)、”rotating”事件(當(dāng)附加到canvas時使用 “object:rotating”)等等。

Groups組

fabric.Group是Fabric.js提供的強(qiáng)大的功能之一。使用Groups可以將任何Fabric對象組合成一個單一實體,這樣就能夠?qū)⑦@些對象作為一個單一的單元來處理。用鼠標(biāo)將畫布上的任意數(shù)量的Fabric對象進(jìn)行組合,一旦組合后,這些對象都可以一起移動甚至修改。它們組成了一個組。我們可以對該組進(jìn)行縮放、旋轉(zhuǎn),甚至改變其呈現(xiàn)屬性—顏色、透明度、邊框等。

下面創(chuàng)建一個由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);


組成組以后,依舊可以對每個對象操作,改變對象的屬性和狀態(tài)。

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

group.item(1).set({

  text: 'trololo',

  fill: 'white'

});


Serialization序列化

為構(gòu)建某種有狀態(tài)的應(yīng)用程序,允許用戶將canvas內(nèi)容的結(jié)果保存在服務(wù)器上,或者將內(nèi)容流媒體化到不同的客戶端。Fabric.js提供了canvas序列化/解序列化支持。

toObject, toJSON

Fabric中序列化的主要方法是 fabric.Canvas#toObject()和 fabric.Canvas#toJSON()方法。讓我們來看一個簡單的例子,首先對一個空畫布進(jìn)行序列化。

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

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


使用的是ES5 JSON.stringify()方法,如果傳入的對象存在toJSON方法,那么這個方法就會隱含地調(diào)用toJSON方法。由于Fabric中的canvas實例有toJSON方法,所以調(diào)用JSON.stringify(canvas)方法和調(diào)用JSON.stringify(canvas.toJSON())一樣。

注意,返回的字符串表示空的canvas。它是JSON格式的,本質(zhì)上由 “objects”和”background”屬性組成。”objects”目前是空的,因為canvas上沒有任何東西,而 background 有一個默認(rèn)的透明值(“rgba(0,0,0,0,0)”)。
當(dāng)在canvas上添加了具體對象后:

canvas.add(new fabric.Circle({

  left: 100,

  top: 100,

  radius: 50,

  fill: 'red'

}));

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


序列化后結(jié)果如下:

'{"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());


序列化結(jié)果如下:

<?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,與序列化時相對應(yīng)的,也有兩種方法:從JSON文本反序列和從SVG文本反序列化。當(dāng)使用JSON表示時,有 fabric.Canvas#loadfromJSON和 fabric.Canvas#loadfromDatalessJSON方法。當(dāng)使用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官網(wǎng):http://fabricjs.com/
fabric.js源碼:https://github.com/fabricjs/fabric.js
fabric.js應(yīng)用案例: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 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved