Fabricjs做组态和流程图-认识Fabricjs(1)

前端外刊评论 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 的对象

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

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的解析,渲染,序列化,事件,图片过滤等等。。。

相关推荐

hyxinyu / 0评论 2020-04-27