diagram-js
Version:
A toolbox for displaying and modifying diagrams on the web
175 lines (134 loc) • 3.83 kB
JavaScript
import SnapContext from './SnapContext';
import {
bottomRight,
getChildren,
isSnapped,
setSnapped,
topLeft,
} from './SnapUtil';
import { isCmd } from '../keyboard/KeyboardUtil';
import {
asTRBL,
getMid
} from '../../layout/LayoutUtil';
import { forEach } from 'min-dash';
import {
isConnection,
isLabel
} from '../../util/ModelUtil';
/**
* @typedef {import('../../core/EventBus').default} EventBus
* @typedef {import('./Snapping').default} Snapping
*/
var HIGHER_PRIORITY = 1250;
/**
* Snap during resize.
*
* @param {EventBus} eventBus
* @param {Snapping} snapping
*/
export default function ResizeSnapping(eventBus, snapping) {
var self = this;
eventBus.on([ 'resize.start' ], function(event) {
self.initSnap(event);
});
eventBus.on([
'resize.move',
'resize.end',
], HIGHER_PRIORITY, function(event) {
var context = event.context,
shape = context.shape,
parent = shape.parent,
direction = context.direction,
snapContext = context.snapContext;
if (event.originalEvent && isCmd(event.originalEvent)) {
return;
}
if (isSnapped(event)) {
return;
}
var snapPoints = snapContext.pointsForTarget(parent);
if (!snapPoints.initialized) {
snapPoints = self.addSnapTargetPoints(snapPoints, shape, parent, direction);
snapPoints.initialized = true;
}
if (isHorizontal(direction)) {
setSnapped(event, 'x', event.x);
}
if (isVertical(direction)) {
setSnapped(event, 'y', event.y);
}
snapping.snap(event, snapPoints);
});
eventBus.on([ 'resize.cleanup' ], function() {
snapping.hide();
});
}
ResizeSnapping.prototype.initSnap = function(event) {
var context = event.context,
shape = context.shape,
direction = context.direction,
snapContext = context.snapContext;
if (!snapContext) {
snapContext = context.snapContext = new SnapContext();
}
var snapOrigin = getSnapOrigin(shape, direction);
snapContext.setSnapOrigin('corner', {
x: snapOrigin.x - event.x,
y: snapOrigin.y - event.y
});
return snapContext;
};
ResizeSnapping.prototype.addSnapTargetPoints = function(snapPoints, shape, target, direction) {
var snapTargets = this.getSnapTargets(shape, target);
forEach(snapTargets, function(snapTarget) {
snapPoints.add('corner', bottomRight(snapTarget));
snapPoints.add('corner', topLeft(snapTarget));
});
snapPoints.add('corner', getSnapOrigin(shape, direction));
return snapPoints;
};
ResizeSnapping.$inject = [
'eventBus',
'snapping'
];
ResizeSnapping.prototype.getSnapTargets = function(shape, target) {
return getChildren(target).filter(function(child) {
return !isAttached(child, shape)
&& !isConnection(child)
&& !isHidden(child)
&& !isLabel(child);
});
};
// helpers //////////
function getSnapOrigin(shape, direction) {
var mid = getMid(shape),
trbl = asTRBL(shape);
var snapOrigin = {
x: mid.x,
y: mid.y
};
if (direction.indexOf('n') !== -1) {
snapOrigin.y = trbl.top;
} else if (direction.indexOf('s') !== -1) {
snapOrigin.y = trbl.bottom;
}
if (direction.indexOf('e') !== -1) {
snapOrigin.x = trbl.right;
} else if (direction.indexOf('w') !== -1) {
snapOrigin.x = trbl.left;
}
return snapOrigin;
}
function isAttached(element, host) {
return element.host === host;
}
function isHidden(element) {
return !!element.hidden;
}
function isHorizontal(direction) {
return direction === 'n' || direction === 's';
}
function isVertical(direction) {
return direction === 'e' || direction === 'w';
}