Adding support for ports and connectors to Fabric.js
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:
- Stackoverflow: Fabric.js - How to determine which (object) control has been clicked?
- Stackoverflow: Fabric.js - How to detect 'mouse:over' object path?
- Stackoverflow: Fabric.js - How to get mouse co-ordinates?
- Stackoverflow: Fabric.js - Show borders on 'mouse:over'?
- Stackoverflow: Fabric.js - How to draw an arrow?
- Stackoverflow: Fabric.js - Undo/Redo
- Stackoverflow: Fabric.js - More Undo/Redo
- Swapnil Jain: Fabric.js - Questions and Answers
- ng-newsletter: AngularJS - Dependency Injection
- Stackoverflow: AngularJS - Should I use angular.copy or ?
- Stackoverflow: Test if point is in some rectangle?
- Joshua Cantrell: Collision Detection Techniques for 2D
- HTML Color Codes: 140 HTML Color Names, Hex Color Codes & RGB Values
- Erik Flowers: The Subtle Magic Behind Why the Bootstrap 3 Grid Works
- AWWWARDS: Trendy Web Color Palettes
Source Code:
- GitHub: My 2D Diagram Editor