如何通过在FabricJS中拖动鼠标来在形状之间绘制连接线

时间:2018-05-03 06:35:09

标签: javascript html5-canvas angular5 fabricjs

我正在尝试使用Fabric js构建状态机类型的流程图。到目前为止,我能够动态添加形状,只需在固定点之间绘制线条。 通过将鼠标从一个组件拖动到另一个组件,我坚持在形状之间绘制连接线。是否真的可以使用FabricJS?如果有,那是什么方法?

有人可以对此有所了解吗?

这是我到目前为止所拥有的,



import {
  Component
} from '@angular/core';
import 'fabric';

declare
let fabric;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  private canvas;
  private boundBox;
  private shape;

  ngOnInit() {

    // https://jsfiddle.net/ka7nhvbq/2/
    // http://jsfiddle.net/xvcyzh9p/45/

    this.canvas = new fabric.Canvas('canvas', {

    })

    this.shape = new fabric.Rect({
      width: 200,
      height: 200,
      top: 300,
      left: 200,
      fill: 'red',
      hasControls: false
    })

    this.canvas.add(this.shape)
    this.canvas.centerObject(this.boundBox)
  }

  getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
  }



  addGambit() {
    let shape = new fabric.Rect({
      width: 200,
      height: 200,
      fill: this.getRandomColor(),
      hasControls: false
    })
    this.canvas.add(shape)
  }
  // By Simon Sarris

  addChildLine(options) {
    this.canvas.off('object:selected', this.addChildLine);

    // add the line
    var fromObject = this.canvas.addChild.start;
    var toObject = options.target;
    var from = fromObject.getCenterPoint();
    var to = toObject.getCenterPoint();
    var line = new fabric.Line([from.x, from.y, to.x, to.y], {
      fill: 'red',
      stroke: 'red',
      strokeWidth: 5,
      selectable: false
    });
    this.canvas.add(line);
    // so that the line is behind the connected shapes
    line.sendToBack();

    // add a reference to the line to each object
    fromObject.addChild = {
      // this retains the existing arrays (if there were any)
      from: (fromObject.addChild && fromObject.addChild.from) || [],
      to: (fromObject.addChild && fromObject.addChild.to)
    }
    fromObject.addChild.from.push(line);
    toObject.addChild = {
      from: (toObject.addChild && toObject.addChild.from),
      to: (toObject.addChild && toObject.addChild.to) || []
    }
    toObject.addChild.to.push(line);

    // to remove line references when the line gets removed
    line.addChildRemove = function() {
      fromObject.addChild.from.forEach(function(e, i, arr) {
        if (e === line)
          arr.splice(i, 1);
      });
      toObject.addChild.to.forEach(function(e, i, arr) {
        if (e === line)
          arr.splice(i, 1);
      });
    }

    // undefined instead of delete since we are anyway going to do this many times
    this.canvas.addChild = undefined;
  }

  addChildMoveLine(event) {
    this.canvas.on(event, function(options) {
      var object = options.target;
      var objectCenter = object.getCenterPoint();
      // udpate lines (if any)
      if (object.addChild) {
        if (object.addChild.from)
          object.addChild.from.forEach(function(line) {
            line.set({
              'x1': objectCenter.x,
              'y1': objectCenter.y
            });
          })
        if (object.addChild.to)
          object.addChild.to.forEach(function(line) {
            line.set({
              'x2': objectCenter.x,
              'y2': objectCenter.y
            });
          })
      }

      this.canvas.renderAll();
    });
  }

  addChild() {
    this.canvas.addChild = {
      start: this.canvas.getActiveObject()
    }

    // for when addChild is clicked twice
    this.canvas.off('object:selected', this.addChildLine);
    this.canvas.on('object:selected', this.addChildLine);
  }

}
&#13;
<canvas width="800" height="800" id="canvas" class="canvas" style="border: 1px solid #666"></canvas>
<button (click)="addGambit()">add gambit</button>
&#13;
&#13;
&#13;

0 个答案:

没有答案