feat(snapping): snap to task mid on center interaction

Closes #1086
This commit is contained in:
Niklas Kiefer 2019-06-19 08:02:00 +02:00 committed by merge-me[bot]
parent cfad2f49aa
commit 9b9ff934d2
2 changed files with 94 additions and 7 deletions

View File

@ -11,7 +11,10 @@ import {
import { is } from '../../util/ModelUtil';
import { some } from 'min-dash';
import {
every,
some
} from 'min-dash';
import { isAny } from '../modeling/util/ModelingUtil';
@ -21,6 +24,8 @@ var BOUNDARY_TO_HOST_THRESHOLD = 40;
var TARGET_BOUNDS_PADDING = 20;
var TARGET_CENTER_PADDING = 20;
var AXES = [ 'x', 'y' ];
var abs = Math.abs;
@ -55,7 +60,7 @@ export default function BpmnConnectSnapping(eventBus, rules) {
});
if (target && connectionAttrs) {
snapInsideTarget(event, target);
snapInsideTarget(event, target, getTargetBoundsPadding(target));
}
if (target && isAnyType(connectionAttrs, [
@ -72,6 +77,10 @@ export default function BpmnConnectSnapping(eventBus, rules) {
snapToPosition(event, mid(target));
}
if (is(target, 'bpmn:Task')) {
snapTargetMidOnCenter(event, target);
}
if (is(source, 'bpmn:BoundaryEvent') && target === source.host) {
snapBoundaryEventLoop(event, source, target);
}
@ -103,16 +112,16 @@ BpmnConnectSnapping.$inject = [
'rules'
];
function snapInsideTarget(event, target) {
function snapInsideTarget(event, target, padding) {
AXES.forEach(function(axis) {
var matchingTargetDimension = getDimensionForAxis(axis, target),
newCoordinate;
if (event[axis] < target[axis] + TARGET_BOUNDS_PADDING) {
newCoordinate = target[axis] + TARGET_BOUNDS_PADDING;
} else if (event[axis] > target[axis] + matchingTargetDimension - TARGET_BOUNDS_PADDING) {
newCoordinate = target[axis] + matchingTargetDimension - TARGET_BOUNDS_PADDING;
if (event[axis] < target[axis] + padding) {
newCoordinate = target[axis] + padding;
} else if (event[axis] > target[axis] + matchingTargetDimension - padding) {
newCoordinate = target[axis] + matchingTargetDimension - padding;
}
if (newCoordinate) {
@ -121,6 +130,23 @@ function snapInsideTarget(event, target) {
});
}
// snap to target mid if event position in center area
function snapTargetMidOnCenter(event, target) {
var isCenter = every(AXES, function(axis) {
var coordinate = event[axis],
matchingTargetDimension = getDimensionForAxis(axis, target);
return coordinate > target[axis] + TARGET_CENTER_PADDING
&& coordinate < target[axis] + matchingTargetDimension - TARGET_CENTER_PADDING;
});
if (isCenter) {
snapToPosition(event, mid(target));
}
}
// snap outside of Boundary Event surroundings
function snapBoundaryEventLoop(event, source, target) {
var sourceMid = mid(source),
@ -171,3 +197,11 @@ function isAnyType(attrs, types) {
function getDimensionForAxis(axis, element) {
return axis === 'x' ? element.width : element.height;
}
function getTargetBoundsPadding(target) {
if (is(target, 'bpmn:Task')) {
return 10;
} else {
return TARGET_BOUNDS_PADDING;
}
}

View File

@ -142,6 +142,59 @@ describe('features/snapping - BpmnConnectSnapping', function() {
});
describe('Task target', function() {
it('should snap to task mid',
inject(function(connect, dragging, elementRegistry) {
// given
var startEvent = elementRegistry.get('StartEvent_1'),
task = elementRegistry.get('Task_1'),
taskGfx = elementRegistry.getGraphics(task);
// when
connect.start(canvasEvent({ x: 210, y: 60 }), startEvent);
dragging.hover({ element: task, gfx: taskGfx });
dragging.move(canvasEvent({ x: 300, y: 300 }));
dragging.end();
// then
var waypoints = startEvent.outgoing[0].waypoints;
expect(waypoints[3].y).to.eql(300);
})
);
it('should snap to grid point',
inject(function(connect, dragging, elementRegistry) {
// given
var startEvent = elementRegistry.get('StartEvent_1'),
task = elementRegistry.get('Task_1'),
taskGfx = elementRegistry.getGraphics(task);
// when
connect.start(canvasEvent({ x: 210, y: 60 }), startEvent);
dragging.hover({ element: task, gfx: taskGfx });
dragging.move(canvasEvent({ x: 300, y: 260 }));
dragging.end();
// then
var waypoints = startEvent.outgoing[0].waypoints;
expect(waypoints[3].y).to.eql(270);
})
);
});
it('should snap event if close to target bounds',
inject(function(connect, dragging, elementRegistry) {