UNPKG

@benson.liao/react-design-editor

Version:

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

275 lines (274 loc) 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fabric_1 = require("fabric"); class NodeHandler { constructor(handler) { /** * Get the node path by target object * @param {NodeObject} target * @param {NodeObject[]} [nodes=[]] * @param {string} [direction='init'] */ this.getNodePath = (target, nodes = [], direction = 'init') => { if (target) { if (direction === 'to' || direction === 'init') { if (target.toPort) { target.toPort.links.forEach(link => { if (link.fromNode) { nodes.push(link.fromNode); this.getNodePath(link.fromNode, nodes, 'to'); } }); } if (direction === 'init') { nodes.push(target); } } if (direction === 'from' || direction === 'init') { target.fromPort.forEach(port => { port.links.forEach(link => { if (link.toNode) { nodes.push(link.toNode); this.getNodePath(link.toNode, nodes, 'from'); } }); }); } } }; /** * Select the node path * @param {string[]} [path] */ this.selectByPath = (path) => { if (!path || !path.length) { return; } const targetObjects = this.handler.objects.filter(object => path.some(id => id === object.id)); const nonTargetObjects = this.handler.objects.filter(object => path.some(id => id !== object.id)); nonTargetObjects.forEach((object) => { if (object.superType === 'link') { const { fromNode, toNode } = object; if (fromNode && toNode) { const fromIndex = targetObjects.findIndex(obj => obj.id === fromNode.id); const toIndex = targetObjects.findIndex(obj => obj.id === toNode.id); if (fromIndex >= 0 && targetObjects[fromIndex] && toIndex >= 0 && targetObjects[toIndex]) { object.set({ opacity: 1, }); object.setShadow({ color: object.stroke, }); this.highlightingNode(object, 300); this.handler.canvas.requestRenderAll(); return; } } } object.set({ opacity: 0.2, }); if (object.superType === 'node') { if (object.toPort) { object.toPort.set({ opacity: 0.2, }); } object.fromPort.forEach((port) => { port.set({ opacity: 0.2, }); }); } if (!object.animating) { object.setShadow({ blur: 0, }); } }); targetObjects.forEach((object) => { object.set({ opacity: 1, }); object.setShadow({ color: object.stroke, }); this.highlightingNode(object, 300); if (object.toPort) { object.toPort.set({ opacity: 1, }); } if (object.fromPort) { object.fromPort.forEach((port) => { port.set({ opacity: 1, }); }); } }); this.handler.canvas.requestRenderAll(); }; /** * Select node by id * @param {string} id */ this.selectById = (id) => { this.handler.objects.forEach((object) => { if (id === object.id) { object.setShadow({ color: object.stroke, blur: 50, }); return; } else if (id === object.nodeId) { return; } object.setShadow({ blur: 0, }); }); this.handler.canvas.requestRenderAll(); }; /** * Deselect nodes */ this.deselect = () => { this.handler.objects.forEach((object) => { object.set({ opacity: 1, }); if (object.superType === 'node') { const node = object; if (node.toPort) { node.toPort.set({ opacity: 1, }); } node.fromPort.forEach(port => { port.set({ opacity: 1, }); }); } if (!object.animating) { const node = object; node.setShadow({ blur: 0, }); } }); this.handler.canvas.renderAll(); }; /** * Highlight node path * @param {string[]} [path] */ this.highlightingByPath = (path) => { if (!path || !path.length) { return; } const targetObjects = this.handler.objects.filter((obj) => path.some(id => id === obj.id)); const nonTargetObjects = this.handler.objects.filter((obj) => path.some(id => id !== obj.id)); const lastObject = targetObjects.filter((obj) => obj.id === path[path.length - 1])[0]; targetObjects.forEach((object) => { if (lastObject) { object.setShadow({ color: lastObject.stroke, }); } else { object.setShadow({ color: object.stroke, }); } this.highlightingNode(object); this.handler.canvas.requestRenderAll(); }); nonTargetObjects.forEach((object) => { if (object.superType === 'link') { const { fromNode, toNode } = object; if (fromNode && toNode) { const fromIndex = targetObjects.findIndex((obj) => obj.id === fromNode.id); const toIndex = targetObjects.findIndex((obj) => obj.id === toNode.id); if (fromIndex >= 0 && targetObjects[fromIndex] && toIndex >= 0 && targetObjects[toIndex]) { if (lastObject) { object.setShadow({ color: lastObject.stroke, }); } else { object.setShadow({ color: object.stroke, }); } this.highlightingNode(object); this.highlightingLink(object, lastObject); return; } } } }); this.handler.canvas.requestRenderAll(); }; /** * Highlight link * @param {FabricObject} object * @param {FabricObject} targetObject * @param {number} [duration=500] */ this.highlightingLink = (object, targetObject, duration = 500) => { object.animation = { duration, type: 'flash', stroke: targetObject ? targetObject.stroke : object.stroke, loop: 1, delay: 0, }; this.handler.animationHandler.play(object.id, false); }; /** * Highlight node * * @param {*} object * @param {number} [duration=500] * @param {number} [minBlur=0] * @param {number} [maxBlur=50] */ this.highlightingNode = (object, duration = 500, minBlur = 0, maxBlur = 50) => { const onComplete = () => { if (object.shadow.blur === maxBlur) { object.animating = true; object.animate('shadow.blur', minBlur, { easing: fabric_1.fabric.util.ease.easeInOutQuad, onChange: (value) => { object.shadow.blur = value; this.handler.canvas.requestRenderAll(); }, onComplete: () => { object.animating = false; if (object.superType === 'link') { object.set({ stroke: object.originStroke, }); } }, }); } }; object.animating = true; object.animate('shadow.blur', maxBlur, { easing: fabric_1.fabric.util.ease.easeInOutQuad, duration, onChange: (value) => { object.shadow.blur = value; this.handler.canvas.requestRenderAll(); }, onComplete, }); }; this.handler = handler; } } exports.default = NodeHandler;