1. 程式人生 > >Fabric.js 簡單介紹和使用

Fabric.js 簡單介紹和使用

來源:https://segmentfault.com/a/1190000004864237

簡介

Fabric.js是一個可以簡化canvas程式編寫的庫。 Fabric.js為canvas提供所缺少的物件模型, svg parser, 互動和一整套其他不可或缺的工具。基於MIT協議開源,在github上有許多人貢獻程式碼。

Why fabric?

canvas提供一個好的畫布能力, 但其api超級爛。如果你就想畫個簡單圖形, 其實也可以, 不過做一些複雜的圖形繪製, 編寫一些複雜的效果,就不是那麼好了。
fabric就是為此而開發。

用物件的方式去編寫程式碼

舉個例子
傳統的畫正方形程式碼

// reference canvas element (with id="c")
var canvasEl = document.getElementById('c'); // get 2d context to draw on (the "bitmap" mentioned earlier) var ctx = canvasEl.getContext('2d'); // set fill color of context ctx.fillStyle = 'red'; // create rectangle at a 100,100 point, with 20x20 dimensions ctx.fillRect(100, 100, 20, 20);

使用fabric

// create a wrapper around native
canvas element (with id="c") var canvas = new fabric.Canvas('c'); // create a rectangle object var rect = new fabric.Rect({ left: 100, top: 100, fill: 'red', width: 20, height: 20 }); // "add" rectangle onto canvas canvas.add(rect);

好的 其實並沒有什麼差別 不過我們試著旋轉一下角度

var canvasEl = document.getElementById('c');
var ctx = canvasEl.getContext('2
d'); ctx.fillStyle = 'red'; ctx.translate(100, 100); ctx.rotate(Math.PI / 180 * 45); ctx.fillRect(-10, -10, 20, 20);

fabric

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

// create a rectangle with angle=45
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 20,
  height: 20,
  angle: 45
});

canvas.add(rect);

如果我們想重新調整位置 怎麼辦

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

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

// erase entire canvas area
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
ctx.fillRect(20, 50, 20, 20);

fabric

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

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

objects

  1. fabric.Circle

  2. fabric.Ellipse

  3. fabric.Line

  4. fabric.Polygon

  5. fabric.Polyline

  6. fabric.Rect

  7. fabric.Triangle

畫一個三角形 和一個 圓形

// create a wrapper around native canvas element (with id="c")
var canvas = new fabric.Canvas('c');

var circle = new fabric.Circle({
    radius: 20, fill: 'green', left: 100, top: 100
});
var triangle = new fabric.Triangle({
    width: 20, height: 30, fill: 'blue', left: 50, top: 50
});

canvas.add(circle, triangle);

Manipulating objects

可以簡單的使用set來控制物件屬性
positioning — left, top; 
dimension — width, height; 
rendering — fill, opacity, stroke, strokeWidth; 
scaling and rotation — scaleX, scaleY, angle; 
and even those related to flipping — flipX, flipY.

rect.set('fill', 'red');
rect.set({ strokeWidth: 5, stroke: 'rgba(100,200,200,0.5)' });
rect.set('angle', 15).set('flipY', true);

有了set 其實也就有了get

物件可以建立時設定屬性 也可以先例項化 再賦值

var rect = new fabric.Rect({ width: 10, height: 20, fill: '#f55', opacity: 0.7 });

// or functionally identical

var rect = new fabric.Rect();
rect.set({ width: 10, height: 20, fill: '#f55', opacity: 0.7 });

另外這裡的fabric.Rect是函式 大家可以使用class繼承

預設值

var rect = new fabric.Rect(); // notice no options passed in

rect.getWidth(); // 0
rect.getHeight(); // 0

rect.getLeft(); // 0
rect.getTop(); // 0

rect.getFill(); // rgb(0,0,0)
rect.getStroke(); // null

rect.getOpacity(); // 1

Hierarchy and Inheritance

fabric.Object 是影象基類

你可以自己擴充方法

fabric.Object.prototype.getAngleInRadians = function() {
  return this.getAngle() / 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

Canvas

fabric.Canvas 是canvas的wrapper

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

canvas.add(rect); // add object

canvas.item(0); // reference fabric.Rect added earlier (first object)
canvas.getObjects(); // get all objects on canvas (rect will be first and only)

canvas.remove(rect); // remove previously-added fabric.Rect

經典的設計 有options 有物件方法

var canvas = new fabric.Canvas('c', {
  backgroundColor: 'rgb(100,100,200)',
  selectionColor: 'blue',
  selectionLineWidth: 2
  // ...
});

// or

var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage(http://...');
canvas.onFpsUpdate = function(){ /* ... */ };
// ...

Images

使用fabric.Image你可以輕鬆的載入一個圖片
html

<canvas id="c"></canvas>
<img src="my_image.png" id="my-image">

js

var canvas = new fabric.Canvas('c');
var imgElement = document.getElementById('my-image');
var imgInstance = new fabric.Image(imgElement, {
  left: 100,
  top: 100,
  angle: 30,
  opacity: 0.85
});
canvas.add(imgInstance);

當然也可以通過url載入一張圖片到canvas

fabric.Image.fromURL('my_image.png', function(oImg) {
  canvas.add(oImg);
});

可以對載入的圖片進行預處理

fabric.Image.fromURL('my_image.png', function(oImg) {
  // scale image down, and flip it, before adding it onto canvas
  oImg.scale(0.5).setFlipX(true);
  canvas.add(oImg);
});

Path and PathGroup

我們已經看了簡單的形狀,然後影象。更復雜、豐富的形狀和內容呢?
路徑包括一系列的命令,這基本上模仿一個筆從一個點到另一個。在“移動”,“線”,“曲線”,或“弧”等命令的幫助下,路徑可以形成令人難以置信的複雜形狀。同組的路徑(路徑組的幫助),開放更多的可能性。
類似於svg的path

var canvas = new fabric.Canvas('c');
var path = new fabric.Path('M 0 0 L 200 100 L 170 200 z');
path.set({ left: 120, top: 120 });
canvas.add(path);

“M” 代表 “move” 命令, 告訴筆到 0, 0 點.
“L” 代表 “line” 畫一條0, 0 到 200, 100 的線. 
another “L” creates a line to 170, 200.
z” tells forces drawing pen to close current path and finalize the shape.

...
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);

path也可以設定canvas屬性

當然 太困然了 所以你可以使用 fabric.loadSVGFromString or fabric.loadSVGFromURL 方法