In a previous post, I described the steps I followed to start working with Fabric.js. In this post, I'll describe the steps I followed to add support for ports and connectors.

Interactivity

Out of the box Fabric.js enables you to select objects:

You can also drag them around, scale or rotate them (and group them together).

Ports

Fabric.js also includes an event model, which means that we can register an event listener that will be invoked when an event is fired.

For example, we can use the 'mouse:over' event:

service.canvas.on('mouse:over', function(element) {

  ...
  service.selectedObject.set('active', true);
  service.selectedObject.set('hasRotatingPoint', false);
  service.selectedObject.set('hasBorders', false);
  service.selectedObject.set('transparentCorners', false);
  service.selectedObject.setControlsVisibility({ tl: false, tr: false,
    br: false, bl: false });
  ...
};

And by hiding the 'tl' (top left), 'tr' (top right), 'br' (bottom right) and 'bl' (bottom left) controls, the remaining controls can act as our (connector) ports:

Connectors

To draw connectors we'll need to register listener's for Fabric's 'mouse:down':

service.canvas.on('mouse:down', function(element) {

  ...
  
  service.isMouseDown = true;

  points = findTargetPort(service.fromObject);
  service.connectorLineFromPort = service.fromObject.__corner;

  service.connectorLine = service.addLine(points, options);

  ...
};

'mouse:move':

service.canvas.on('mouse:move', function(element) {

  ...
  
  var pointer = service.canvas.getPointer(object.e);

  service.connectorLine.set({ x2: pointer.x, y2: pointer.y });
  service.canvas.renderAll();

  ...
};

and 'mouse:up' events:

service.canvas.on('mouse:up', function(element) {

  ...
  
  service.isMouseDown = false;

  portCenter = getPortCenterPoint(service.selectedObject, toPort);
  service.connectorLine.set({ x2: portCenter.x2, y2: portCenter.y2 });

  ...
};

We can also add arrows to the connectors:

and update their position when an object is dragged around ('object:move'):

What's Next

In the next post, we'll add support for formatting shapes and containers:

References:
Source Code: