| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- import { is, isAny } from '../../../utils/modelUtil';
- import { findFreePosition, generateGetNextPosition, getConnectedDistance } from '../../../autoPlace/YmAutoPlaceUtil';
- import { isObject } from 'min-dash';
- import { typeLabel, typeTrigger } from '../../../config/variableName';
- var HIGH_PRIORITY = 2000;
- function distance(a: any, b: any) {
- return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
- }
- /**
- * Convert the given bounds to a { top, left, bottom, right } descriptor.
- * @param {Point|Rect} bounds
- * @return {RectTRBL}
- *
- */
- export function asTRBL(bounds: any) {
- return {
- top: bounds.y,
- right: bounds.x + (bounds.width || 0),
- bottom: bounds.y + (bounds.height || 0),
- left: bounds.x,
- };
- }
- export function getConnectionMid(connection: any) {
- var waypoints = connection.waypoints;
- var parts = waypoints.reduce(function (parts: any, point: any, index: any) {
- var lastPoint = waypoints[index - 1];
- if (lastPoint) {
- var lastPart = parts[parts.length - 1];
- var startLength = (lastPart && lastPart.endLength) || 0;
- var length = distance(lastPoint, point);
- parts.push({
- start: lastPoint,
- end: point,
- startLength: startLength,
- endLength: startLength + length,
- length: length,
- });
- }
- return parts;
- }, []);
- var totalLength = parts.reduce(function (length: any, part: any) {
- return length + part.length;
- }, 0);
- var midLength = totalLength / 2;
- var i = 0;
- var midSegment = parts[i];
- while (midSegment.endLength < midLength) {
- midSegment = parts[++i];
- }
- var segmentProgress = (midLength - midSegment.startLength) / midSegment.length;
- var midPoint = {
- x: midSegment.start.x + (midSegment.end.x - midSegment.start.x) * segmentProgress,
- y: midSegment.start.y + (midSegment.end.y - midSegment.start.y) * segmentProgress,
- };
- return midPoint;
- }
- export function roundPoint(point: any) {
- return {
- x: Math.round(point.x),
- y: Math.round(point.y),
- };
- }
- export function getBoundsMid(bounds: any) {
- return roundPoint({
- x: bounds.x + (bounds.width || 0) / 2,
- y: bounds.y + (bounds.height || 0) / 2,
- });
- }
- export function getMid(element: any) {
- if (!!element.waypoints) return getConnectionMid(element);
- return getBoundsMid(element);
- }
- export function getOrientation(rect: any, reference: any, padding: any) {
- padding = padding || 0;
- if (!isObject(padding)) padding = { x: padding, y: padding };
- var rectOrientation = asTRBL(rect),
- referenceOrientation = asTRBL(reference);
- var top = rectOrientation.bottom + padding.y <= referenceOrientation.top,
- right = rectOrientation.left - padding.x >= referenceOrientation.right,
- bottom = rectOrientation.top - padding.y >= referenceOrientation.bottom,
- left = rectOrientation.right + padding.x <= referenceOrientation.left;
- var vertical = top ? 'top' : bottom ? 'bottom' : null,
- horizontal = left ? 'left' : right ? 'right' : null;
- if (horizontal && vertical) return vertical + '-' + horizontal;
- else return horizontal || vertical || 'intersect';
- }
- /**
- * Always try to place element right of source;
- * compute actual distance from previous nodes in flow.
- */
- export function getFlowNodePosition(source: any, element: any) {
- var sourceTrbl = asTRBL(source); // 描述图形或区域在页面或画布上的位置和大小
- var sourceMid = getMid(source); // 获取中心点坐标
- var horizontalDistance = getConnectedDistance(source, {
- direction: 's',
- filter: function (connection: any) {
- return is(connection, 'bpmn:SequenceFlow');
- },
- });
- var margin = 30,
- minDistance = 50,
- orientation = 'top';
- if (is(source, 'bpmn:BoundaryEvent')) {
- orientation = getOrientation(source, source.host, -25);
- if (orientation.indexOf('top') !== -1) margin *= -1;
- }
- var position: any = {};
- position = {
- // x: sourceTrbl.right + horizontalDistance + element.width / 2,
- // y: sourceMid.y + getVerticalDistance(orientation, minDistance),
- x: sourceMid.x,
- y: sourceTrbl.bottom + horizontalDistance + element.height / 2,
- };
- // y轴距离
- var nextPositionDirection = {
- x: {
- margin: margin,
- minDistance: minDistance,
- },
- };
- return findFreePosition(source, element, position, generateGetNextPosition(nextPositionDirection));
- }
- export function getNewShapePosition(source: any, element: any) {
- if (is(element, 'bpmn:TextAnnotation')) return getTextAnnotationPosition(source, element);
- if (isAny(element, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) return getDataElementPosition(source, element);
- if (is(element, 'bpmn:FlowNode')) return getFlowNodePosition(source, element);
- }
- export function getDataElementPosition(source: any, element: any) {
- var sourceTrbl = asTRBL(source);
- var position = {
- x: sourceTrbl.right - 10 + element.width / 2,
- y: sourceTrbl.bottom + 40 + element.width / 2,
- };
- var nextPositionDirection = {
- x: {
- margin: 30,
- minDistance: 30,
- },
- };
- return findFreePosition(source, element, position, generateGetNextPosition(nextPositionDirection));
- }
- export function getTextAnnotationPosition(source: any, element: any) {
- var sourceTrbl = asTRBL(source);
- var position = {
- x: sourceTrbl.right + element.width / 2,
- y: sourceTrbl.top - 50 - element.height / 2,
- };
- if (!!source.waypoints) {
- position = getMid(source);
- position.x += 100;
- position.y -= 50;
- }
- var nextPositionDirection = {
- y: {
- margin: -30,
- minDistance: 20,
- },
- };
- return findFreePosition(source, element, position, generateGetNextPosition(nextPositionDirection));
- }
- function getNewSourceInLabel(source: any) {
- if (source.type === typeLabel) {
- let connectElement: any = source?.labelTarget;
- if (connectElement?.target) return connectElement.target;
- }
- return source;
- }
- export default function YmGridSnappingAutoPlaceBehavior(eventBus: any, injector: any) {
- eventBus.on('autoPlace', HIGH_PRIORITY, function (context: any) {
- var source = context.source,
- sourceMid = getMid(source),
- shape = context.shape;
- let elementRegistry = injector.get('elementRegistry');
- let element = elementRegistry.get(source.id);
- var position: any = getNewShapePosition(getNewSourceInLabel(element), shape);
- ['x', 'y'].forEach(function (axis: any) {
- var options: any = {};
- if (position[axis] === sourceMid[axis]) return;
- if (position[axis] > sourceMid[axis]) options.min = position[axis];
- else options.max = position[axis];
- if (is(shape, 'bpmn:TextAnnotation')) {
- if (isHorizontal(axis)) options.offset = -shape.width / 2;
- else options.offset = -shape.height / 2;
- }
- });
- let height = shape.wnType === typeTrigger ? 254 : 160;
- position = {
- x: position.x,
- y: Math.abs(position.y - element.y) > 260 ? element.y + height : position.y,
- };
- return position;
- });
- }
- YmGridSnappingAutoPlaceBehavior.$inject = ['eventBus', 'injector'];
- function isHorizontal(axis: any) {
- return axis === 'x';
- }
|