欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-28 10:51:52
在工业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的解析,渲染,序列化,事件,图片过滤等等。。。