How to draw connector lines between shapes by dragging mouse in FabricJS

天涯浪子 提交于 2019-12-11 14:23:19

问题


I'm trying to build a state machine kind of flow diagram using Fabric js. So far I'm able to dynamically add shapes and just draw lines between fixed points. I'm stuck at drawing connector lines between shapes by dragging the mouse from one component to another. Is it really possible using FabricJS? if yes, what are the approaches?

Can anyone throw some light on this?

Here is what I have so far,

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);
  }

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

来源:https://stackoverflow.com/questions/50148390/how-to-draw-connector-lines-between-shapes-by-dragging-mouse-in-fabricjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!