前端外刊评论 2018-02-06
在工业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提供了7中基本的对象类,如果只是单纯的画这些图形的话,会节省我们很多的时间:
这些实例都继承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操作 ,则会使用以下方式:
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<br />
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(){ /* ... */ }; // ...
重点来了,交互-对象模型存在允许编程访问和操纵画布上的对象。但是在用户层面是通过鼠标来操作这个对象的,只要你是通过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 }));
对图片的操作也是同样的
//(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); });
如果我们要画更复杂的图形,则需要使用路经来画
... 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的解析,渲染,序列化,事件,图片过滤等等。。。