繼昨天講了那麼多特性,各種蛛絲馬跡都指出,他是一個 物件導向架構!
以下進行各種比對分析:
Fabric.js 把所有畫布上的東西都當作物件。
⇒ 物件導向架構
物件有 Rect(矩形)、Circle(圓形)、Image(圖片)等都繼承自基本的 Fabric.Object 類別,而特定形狀如 Fabric.Rect 則進一步擴展這個基類。
⇒ 類別和繼承 (Classes and Inheritance)
每個物件封裝了自己的屬性和方法。以下舉例:
屬性:一個矩形物件會有自己的寬度、高度、位置等屬性
方法:移動、縮放等方法。
⇒ 封裝 (Encapsulation)
不同類型的物件如何對相同的方法(如 render()
、toObject()
、animate()
)有不同的實現
// rect 和 circle 是不同形狀的物件,用相同的 animate() 方法,但實現出來的視覺結果會不一樣
rect.animate('left', '+=100', {
onChange: canvas.renderAll.bind(canvas),
duration: 1000
});
circle.animate('top', '+=100', {
onChange: canvas.renderAll.bind(canvas),
duration: 1000
});
⇒ 多型 (Polymorphism)
你可以為特定物件或整個畫布添加事件監聽器, 使用物件導向的方式來處理事件。
⇒ 事件處理 (Event Handling)
由於其物件導向的設計,Fabric.js 很容易擴展。
你可以創建自定義的物件類型,繼承現有的類別並添加新功能。
⇒ 可擴展性 (Extensibility)
這種物件導向的方法使 Fabric.js 變得強大且靈活,允許開發者以一種結構化和可維護的方式來處理複雜的畫布操作。
如果對於物件導向不是很清楚的話推薦這一篇:
物件導向的三大特性 : 封裝,繼承,多型
他用淺顯易懂的方式解釋這些特性
講完物件導向特性後,就讓我們來深入理解 fabric.js 的物件吧:
這是一個矩形物件,使用方式基本上就是 new
一個他 (像是 javascript new
一個物件一樣),並可以直接加屬性在這個物件上
const rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'red',
width: 50,
height: 50
});
⇒ fabric.Canvas
、fabric.StaticCanvas
有 動態畫布 與 靜態畫布 兩種:
動態畫布舉例:
const canvas = new fabric.Canvas('canvas');
// 常見可以設置的屬性
const canvas = new fabric.Canvas('canvas', {
backgroundColor: '#fff',
selection: true,
preserveObjectStacking: true,
hoverCursor: 'pointer',
defaultCursor: 'default',
});
// 也可以事後再加上去
// isDrawingMode 及時控制現在是否為繪畫模式
canvas.set({
isDrawingMode: false,
})
backgroundColor
: 設置畫布的背景顏色。
selection
: 是否允許選擇多個物件,設定 false
的話一次只能選取一個物件
preserveObjectStacking
: 當選擇多個物件時,是否保持物件的堆疊順序。
hoverCursor
: 當滑鼠懸停在物件上時顯示的游標樣式。
defaultCursor
: 當滑鼠在畫布上但不在物件上時顯示的游標樣式。
isDrawingMode
: 是否啟用繪圖模式。
JSDoc: Class: Object (fabricjs.com)
常用屬性在上一篇已介紹,今天不再贅述
fabric.Rect
:矩形對象fabric.Circle
:圓形對象fabric.Triangle
:三角形對象fabric.Line
:線條對象fabric.Polygon
:多邊形對象fabric.Polyline
:折線對象fabric.Ellipse
:橢圓形對象
JSDoc: Class: Text (fabricjs.com)fabric.Text
:文本對象fabric.IText
:可編輯文本對象
處理文本物件
提供文字樣式和排版功能
fabric.Text
特有的其他屬性(常用):
text
: 文本內容。fontSize
: 字體大小。fontWeight
: 字體粗細。fontFamily
: 字體家族。fontStyle
: 字體樣式(如 normal
, italic
)。textAlign
: 文本對齊方式(如 left
, center
, right
)。lineHeight
: 行高。charSpacing
: 字符間距。JSDoc: Class: Image (fabricjs.com)fabric.Image
JSDoc: Class: Path (fabricjs.com)fabric.Path
用於創建複雜形狀和路徑
支持SVG路徑指令
特有屬性(常用)
path
: 路徑數據,通常是一個包含路徑命令的數組。pathOffset
: 路徑的偏移量,包含 x
和 y
屬性,用於調整路徑的起始點。fillRule
: 填充規則,決定如何填充路徑(如 nonzero
或 evenodd
)。strokeDashArray
: 描邊的虛線樣式,通常是一個數字數組。strokeDashOffset
: 描邊虛線的偏移量。strokeLineCap
: 描邊的端點樣式(如 butt
, round
, square
)。strokeLineJoin
: 描邊的連接樣式(如 miter
, round
, bevel
)。strokeMiterLimit
: 描邊的斜接限制。transformMatrix
: 用於變換路徑的矩陣。管理物件群組
允許整體操作多個物件
fabric.Group:對象組
fabric.PathGroup:路徑組對象
特有屬性(常用)
objects
: 包含在該組中的對象數組。。subTargetCheck
: 是否檢查組內的子目標(默認為 false
)。useSetOnGroup
: 是否在組內的對象上應用組的屬性(默認為 false
)。dirty
: 標記組是否需要重新渲染(默認為 false
)。Fabric.js提供了擴展現有類的機制,允許開發者添加自定義方法和屬性:
fabric.util.createClass()
: 用於創建新類fabric.[ClassName].prototype.extend()
: 擴展現有 class這個機制可以玩的東西很多!除了擴展,你也可以擴展原型來覆蓋掉既有的 prototype(在不玩壞現有功能的前提下),這特性讓使用 fabric.js 的自由度變很大。
後續會慢慢介紹更多關於這塊的例子~
為何要大費周章地介紹 fabric.js 的物件導向特性呢?
以下是一些使用這些特性的例子:
在製作物件的控制項時,可以擴展 fabric.Object
類並覆寫其 controls
屬性,這樣所有物件出生的時候都可直接繼承 fabric.Object
上我們客製化的控制項而不是傻傻的每新增一個/一種物件就做一次(像我之前一樣不要學)
(後續會詳細介紹製作物件的控制項的例子)
fabric.js 沒有內建 redo/undo的功能,如果我們在 prototype 裡新增這功能:
fabric.Canvas.prototype.redo = function (callback) {
...前進邏輯
}
fabric.Canvas.prototype.undo = function (callback) {
...回復邏輯
}
你之後在畫布(全域)上就可以直接取用此功能了!🎉canvas.undo();
canvas.undo();
以此類推,很多功能你可以自己寫 extend 的 api 來取用 or 或是覆蓋舊有的屬性
是我自己後來再回來看,理解這些物件導向特性可以更精準、有效率的使用 fabric.js 。
(以下省略一萬字摸索過程中的血與淚QAQ)
明天來繼續聊聊 fabric.js 的事件(event)與渲染(render)