UNPKG

@benson.liao/react-design-editor

Version:

Design Editor Tools with React.js + ant.design + fabric.js

248 lines (247 loc) 8.49 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const warning_1 = __importDefault(require("warning")); const objects_1 = require("../objects"); /** * Link Handler Class * @author salgum1114 * @class LinkHandler */ class LinkHandler { constructor(handler) { this.port = null; /** * On source port click, start link * @param {PortObject} port */ this.init = (port) => { if (this.isDrawing()) { return; } if (this.isConnected(port)) { return; } this.port = port; this.port.set({ fill: port.selectFill, }); this.handler.interactionHandler.linking(); const { left, top, nodeId, id } = port; const fromPort = { left, top, id }; const toPort = { left, top }; const fromNode = this.handler.objectMap[nodeId]; this.handler.activeLine = new objects_1.CurvedLink(fromNode, fromPort, null, toPort, { strokeWidth: 2, fill: '#999999', stroke: '#999999', class: 'line', originX: 'center', originY: 'center', selectable: false, hasBorders: false, hasControls: false, evented: false, }); this.handler.canvas.add(this.handler.activeLine); }; /** * End drawing link. */ this.finish = (link) => { if (!link) { this.port.set({ fill: this.port.originFill, }); } this.handler.interactionHandler.selection(); this.handler.canvas.remove(this.handler.activeLine); this.handler.activeLine = null; this.handler.canvas.renderAll(); }; /** * On dest port click, finish link * @param {PortObject} port */ this.generate = (port) => { if (!port) { warning_1.default(!port, 'Does not exist target port.'); return; } if (this.isDuplicate(port)) { return; } if (this.isSameNode(port)) { return; } const link = { type: 'curvedLink', fromNodeId: this.handler.activeLine.fromNode.id, fromPortId: this.handler.activeLine.fromPort.id, toNodeId: port.nodeId, toPortId: port.id, }; const createdLink = this.create(link); this.finish(createdLink); // TODO... // Save transactions unconditionally if (!this.handler.transactionHandler.active) { this.handler.transactionHandler.save('add'); } }; /** * Add link in Canvas * @param {LinkOption} link * @param {boolean} [loaded=false] * @returns */ this.create = (link, loaded = false) => { const fromNode = this.handler.objectMap[link.fromNodeId]; const fromPort = fromNode.fromPort.filter(port => port.id === link.fromPortId || !port.id)[0]; const toNode = this.handler.objectMap[link.toNodeId]; const { toPort } = toNode; const createdObj = this.handler.fabricObjects[link.type].create(fromNode, fromPort, toNode, toPort, { ...link, }); this.handler.canvas.add(createdObj); this.handler.objects = this.handler.getObjects(); const { editable } = this.handler; if (this.handler.onAdd && editable && !loaded) { this.handler.onAdd(createdObj); } this.handler.canvas.renderAll(); createdObj.setPort(fromNode, fromPort, toNode, toPort); this.handler.portHandler.setCoords(fromNode); this.handler.portHandler.setCoords(toNode); this.handler.canvas.requestRenderAll(); return createdObj; }; /** * Set coordinate of link * @param {number} x1 * @param {number} y1 * @param {number} x2 * @param {number} y2 * @param {LinkObject} link */ this.setCoords = (x1, y1, x2, y2, link) => { link.set({ x1, y1, x2, y2, }); link.setCoords(); }; /** * When the link is deleted, linked FromNode delete * @param {LinkObject} link */ this.removeFrom = (link) => { if (link.fromPort) { let index = -1; if (link.fromPort.links.length) { link.fromPort.links.some((portLink, i) => { if (link.id === portLink.id) { index = i; return true; } return false; }); if (index > -1) { link.fromPort.links.splice(index, 1); } } link.setPortEnabled(link.fromNode, link.fromPort, true); } }; /** * When the link is deleted, linked ToNode delete * @param {LinkObject} link */ this.removeTo = (link) => { if (link.toNode.toPort.links.length) { let index = -1; link.toNode.toPort.links.some((portLink, i) => { if (link.id === portLink.id) { index = i; return true; } return false; }); if (index > -1) { link.toNode.toPort.links.splice(index, 1); } link.setPortEnabled(link.toNode, link.toNode.toPort, true); } }; /** * When the link is deleted, linked node delete * @param {LinkObject} link */ this.removeAll = (link) => { this.removeFrom(link); this.removeTo(link); }; /** * Remove link in canvas * @param {LinkObject} link * @param {string} [type] */ this.remove = (link, type) => { if (type === 'from') { this.removeFrom(link); } else if (type === 'to') { this.removeTo(link); } else { this.removeAll(link); } this.handler.canvas.remove(link); this.handler.objects = this.handler.getObjects(); }; /** * Check if there is a port connected * @param {PortObject} port * @returns */ this.isConnected = (port) => { warning_1.default(port.enabled, 'A connected node already exists.'); return !port.enabled; }; /** * Check if select same node * @param {PortObject} port * @returns */ this.isSameNode = (port) => { const validate = port.nodeId === this.handler.activeLine.fromNode.id; warning_1.default(!validate, 'Cannot select the same node.'); return validate; }; /** * Check if select same node * @param {PortObject} port * @returns */ this.isDuplicate = (port) => { const validate = port.links.some(link => link.fromNode.id === this.handler.activeLine.fromNode.id); warning_1.default(!validate, 'Duplicate connections cannot be made.'); return validate; }; /** * Check if draw the link * @returns */ this.isDrawing = () => { const validate = this.handler.interactionMode === 'link' && this.handler.activeLine; warning_1.default(!validate, 'Already drawing links.'); return validate; }; this.handler = handler; } } exports.default = LinkHandler;