在工業4.0和IOT的驅動下,越來越多的設備開始接入互聯網。對於web和移動端的流行 很多企業開始對設備的監控 從桌面端走到了移動端和web端。雖然目前還是有不少漂亮的UI 是實現組態設計,但是 還是如之前的老式思維一樣,很少有開源的web 來滿足各個需求。現在由於公司需要,開始研究組態設計並選定了 ...
在工業4.0和IOT的驅動下,越來越多的設備開始接入互聯網。對於web和移動端的流行 很多企業開始對設備的監控 從桌面端走到了移動端和web端。雖然目前還是有不少漂亮的UI 是實現組態設計,但是 還是如之前的老式思維一樣,很少有開源的web 來滿足各個需求。現在由於公司需要,開始研究組態設計並選定了這個FabricJS 作為 web 展示的組態設計!
Fabricjs是一個開源的基於canvas的web交互的js庫,開源協議MIT,並有很多貢獻者。英文無障礙者--->http://fabricjs.com
Fabric 提供了canvas 渲染的對象模型,也能對SVG進行了很好的解析和交互,並且可以當作對於其他類似需求的必不可少的工具。它基於原生方法提供了簡單並且強大的對象模型.也考慮到了canvas的狀態和渲染,直接讓我們對對象進行操作即可。後面的文章大部分是摘抄自官網教程,博主是想一邊學,一邊記。所以只是稍微梳理下並做了下翻譯。
比如我們想畫一個紅色矩形,來實現同樣的效果,一下是用原生canvas和Fabric的對比:
將這個矩形旋轉45度:
用原生的canvas就需要:
var canvasEl = document.getElementById('c'); var ctx = canvasEl.getContext('2d'); 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 //旋轉45堵 }); canvas.add(rect);
我們需要計算出在canvas點陣圖中旋轉的距離和畫線的起始位置,然後再將這個舉行畫出來原生的是直接作用於整個canvas,而Fabric 是實例化一個對象,並對這個對象的屬性和事件進行操作再加入到canvas 中。當我們想對這個舉行進行移動的時候,我們用原生canvas API是需要重新清空canvas 再進行重繪,而Fabric直接改變該對象的屬性位置而進行渲染!(emmm...)
看 canvas API
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();
Fabric 的對象
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
你就會發現這些對象都可以使用了。
Canvas
如果我們想對canvas操作 ,則會使用以下方式:
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
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(){ /* ... */ }; // ...
Interactivity(互動)
重點來了,交互-對象模型存在允許編程訪問和操縱畫布上的對象。但是在用戶層面是通過滑鼠來操作這個對象的,只要你是通過fabric.Canvas('...')初始化對象的,它是可以被選擇,拖拽,放大縮小和旋轉,甚至可以分組。如果你想禁用某個交互功能,你只需要配置成boolen傳遞即可:
var canvas = new fabric.Canvas('c'); ... canvas.selection = false; // disable group selection rect.set('selectable', false); // make object unselectable
如果你不想讓這個對象有任何的操作,你可以使用fabric.StaticCanvas對象
var staticCanvas = new fabric.StaticCanvas('c'); staticCanvas.add( new fabric.Rect({ width: 10, height: 20, left: 100, top: 100, fill: 'yellow', angle: 30 }));
Images(圖片)
對圖片的操作也是同樣的
//(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);
也可以直接使用圖片路徑使用fabric.Image.fromURL來渲染:
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); });
Paths(路經)
如果我們要畫更複雜的圖形,則需要使用路經來畫
... 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);
... var path = new fabric.Path('M121.32,0L44.58,0C36.67,0,29.5,3.22,24.31,8.41\ c-5.19,5.19-8.41,12.37-8.41,20.28c0,15.82,12.87,28.69,28.69,28.69c0,0,4.4,\ 0,7.48,0C36.66,72.78,8.4,101.04,8.4,101.04C2.98,106.45,0,113.66,0,121.32\ c0,7.66,2.98,14.87,8.4,20.29l0,0c5.42,5.42,12.62,8.4,20.28,8.4c7.66,0,14.87\ -2.98,20.29-8.4c0,0,28.26-28.25,43.66-43.66c0,3.08,0,7.48,0,7.48c0,15.82,\ 12.87,28.69,28.69,28.69c7.66,0,14.87-2.99,20.29-8.4c5.42-5.42,8.4-12.62,8.4\ -20.28l0-76.74c0-7.66-2.98-14.87-8.4-20.29C136.19,2.98,128.98,0,121.32,0z'); canvas.add(path.set({ left: 100, top: 200 }));
結語
這是介紹的對fabric一些基本的實例對象, 還有一些更複雜的 動畫,文本,SVG的解析,渲染,序列化,事件,圖片過濾等等。。。