123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- import {
- mid,
- setSnapped
- } from 'diagram-js/lib/features/snapping/SnapUtil';
- import { isCmd } from 'diagram-js/lib/features/keyboard/KeyboardUtil';
- import {
- getOrientation
- } from 'diagram-js/lib/layout/LayoutUtil';
- import { is } from '../../util/ModelUtil';
- import { isAny } from '../modeling/util/ModelingUtil';
- import { some } from 'min-dash';
- var HIGHER_PRIORITY = 1250;
- var BOUNDARY_TO_HOST_THRESHOLD = 40;
- var TARGET_BOUNDS_PADDING = 20,
- TASK_BOUNDS_PADDING = 10;
- var TARGET_CENTER_PADDING = 20;
- var AXES = [ 'x', 'y' ];
- var abs = Math.abs;
- /**
- * Snap during connect.
- *
- * @param {EventBus} eventBus
- */
- export default function BpmnConnectSnapping(eventBus) {
- eventBus.on([
- 'connect.hover',
- 'connect.move',
- 'connect.end',
- ], HIGHER_PRIORITY, function(event) {
- var context = event.context,
- canExecute = context.canExecute,
- start = context.start,
- hover = context.hover,
- source = context.source,
- target = context.target;
- // do NOT snap on CMD
- if (event.originalEvent && isCmd(event.originalEvent)) {
- return;
- }
- if (!context.initialConnectionStart) {
- context.initialConnectionStart = context.connectionStart;
- }
- // snap hover
- if (canExecute && hover) {
- snapToShape(event, hover, getTargetBoundsPadding(hover));
- }
- if (hover && isAnyType(canExecute, [
- 'bpmn:Association',
- 'bpmn:DataInputAssociation',
- 'bpmn:DataOutputAssociation',
- 'bpmn:SequenceFlow'
- ])) {
- context.connectionStart = mid(start);
- // snap hover
- if (isAny(hover, [ 'bpmn:Event', 'bpmn:Gateway' ])) {
- snapToPosition(event, mid(hover));
- }
- // snap hover
- if (isAny(hover, [ 'bpmn:Task', 'bpmn:SubProcess' ])) {
- snapToTargetMid(event, hover);
- }
- // snap source and target
- if (is(source, 'bpmn:BoundaryEvent') && target === source.host) {
- snapBoundaryEventLoop(event);
- }
- } else if (isType(canExecute, 'bpmn:MessageFlow')) {
- if (is(start, 'bpmn:Event')) {
- // snap start
- context.connectionStart = mid(start);
- }
- if (is(hover, 'bpmn:Event')) {
- // snap hover
- snapToPosition(event, mid(hover));
- }
- } else {
- // un-snap source
- context.connectionStart = context.initialConnectionStart;
- }
- });
- }
- BpmnConnectSnapping.$inject = [ 'eventBus' ];
- // helpers //////////
- // snap to target if event in target
- function snapToShape(event, target, padding) {
- AXES.forEach(function(axis) {
- var dimensionForAxis = getDimensionForAxis(axis, target);
- if (event[ axis ] < target[ axis ] + padding) {
- setSnapped(event, axis, target[ axis ] + padding);
- } else if (event[ axis ] > target[ axis ] + dimensionForAxis - padding) {
- setSnapped(event, axis, target[ axis ] + dimensionForAxis - padding);
- }
- });
- }
- // snap to target mid if event in target mid
- function snapToTargetMid(event, target) {
- var targetMid = mid(target);
- AXES.forEach(function(axis) {
- if (isMid(event, target, axis)) {
- setSnapped(event, axis, targetMid[ axis ]);
- }
- });
- }
- // snap to prevent loop overlapping boundary event
- function snapBoundaryEventLoop(event) {
- var context = event.context,
- source = context.source,
- target = context.target;
- if (isReverse(context)) {
- return;
- }
- var sourceMid = mid(source),
- orientation = getOrientation(sourceMid, target, -10),
- axes = [];
- if (/top|bottom/.test(orientation)) {
- axes.push('x');
- }
- if (/left|right/.test(orientation)) {
- axes.push('y');
- }
- axes.forEach(function(axis) {
- var coordinate = event[ axis ], newCoordinate;
- if (abs(coordinate - sourceMid[ axis ]) < BOUNDARY_TO_HOST_THRESHOLD) {
- if (coordinate > sourceMid[ axis ]) {
- newCoordinate = sourceMid[ axis ] + BOUNDARY_TO_HOST_THRESHOLD;
- }
- else {
- newCoordinate = sourceMid[ axis ] - BOUNDARY_TO_HOST_THRESHOLD;
- }
- setSnapped(event, axis, newCoordinate);
- }
- });
- }
- function snapToPosition(event, position) {
- setSnapped(event, 'x', position.x);
- setSnapped(event, 'y', position.y);
- }
- function isType(attrs, type) {
- return attrs && attrs.type === type;
- }
- function isAnyType(attrs, types) {
- return some(types, function(type) {
- return isType(attrs, type);
- });
- }
- function getDimensionForAxis(axis, element) {
- return axis === 'x' ? element.width : element.height;
- }
- function getTargetBoundsPadding(target) {
- if (is(target, 'bpmn:Task')) {
- return TASK_BOUNDS_PADDING;
- } else {
- return TARGET_BOUNDS_PADDING;
- }
- }
- function isMid(event, target, axis) {
- return event[ axis ] > target[ axis ] + TARGET_CENTER_PADDING
- && event[ axis ] < target[ axis ] + getDimensionForAxis(axis, target) - TARGET_CENTER_PADDING;
- }
- function isReverse(context) {
- var hover = context.hover,
- source = context.source;
- return hover && source && hover === source;
- }
|