Skip to content

Commit

Permalink
feat(grid-snapping): allow snapping create/move with offset
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Apr 26, 2019
1 parent 261832c commit 2fd65f2
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 22 deletions.
104 changes: 91 additions & 13 deletions lib/features/grid-snapping/GridSnapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { isNumber } from 'min-dash';
var SPACING = 10,
LOWER_PRIORITY = 1200;


/**
* Basic grid snapping that covers connecting, creating, moving, resizing shapes, moving bendpoints
* and connection segments.
*/
export default function GridSnapping(
eventBus,
config,
Expand All @@ -35,18 +38,43 @@ export default function GridSnapping(
});

eventBus.on([
'shape.move.move',
'shape.move.end',
'create.move',
'create.end',
'connect.move',
'connect.end',
'resize.move',
'resize.end',
'shape.move.move',
'shape.move.end'
], LOWER_PRIORITY, function(event) {
var originalEvent = event.originalEvent;

if (!self.active || (originalEvent && isCmd(originalEvent))) {
return;
}

var context = event.context;

[ 'x', 'y' ].forEach(function(axis) {
if (!isSnapped(event, axis)) {
var snapOffset = 0;

// allow snapping to location other than mid
if (context.gridSnappingContext && context.gridSnappingContext.snapLocation) {
snapOffset = getSnapOffset(event, axis);
}

self.snapEvent(event, axis, snapOffset);
}
});

});

eventBus.on([
'bendpoint.move.move',
'bendpoint.move.end',
'connect.move',
'connect.end',
'connectionSegment.move.move',
'connectionSegment.move.end'
'connectionSegment.move.end',
'resize.move',
'resize.end'
], LOWER_PRIORITY, function(event) {
var originalEvent = event.originalEvent;

Expand All @@ -56,21 +84,32 @@ export default function GridSnapping(

[ 'x', 'y' ].forEach(function(axis) {
if (!isSnapped(event, axis)) {
self.snap(event, axis);
self.snapEvent(event, axis);
}
});
});
}

GridSnapping.prototype.snap = function(event, axis) {
/**
* Snap an events x or y.
*
* @param {Object} event - Event.
* @param {string} axis - Axis.
* @param {number} [snapOffset] - Snap offset.
*/
GridSnapping.prototype.snapEvent = function(event, axis, snapOffset) {
if (!snapOffset) {
snapOffset = 0;
}

var snapConstraints = getSnapConstraints(event, axis);

var snappedValue = this._getSnappedValue(event[ axis ], snapConstraints);
var snappedValue = this.snapValue(event[ axis ] + snapOffset, snapConstraints) - snapOffset;

setSnapped(event, axis, snappedValue);
};

GridSnapping.prototype._getSnappedValue = function(value, snapConstraints) {
GridSnapping.prototype.snapValue = function(value, snapConstraints) {
value = quantize(value, SPACING);

var min, max;
Expand Down Expand Up @@ -119,7 +158,7 @@ GridSnapping.$inject = [
* Get minimum and maximum snap constraints.
*
* @param {Object} event - Event.
* @param {String} axis - Axis.
* @param {string} axis - Axis.
*
* @returns {Object}
*/
Expand Down Expand Up @@ -184,6 +223,45 @@ function getSnapConstraints(event, axis) {
return snapConstraints;
}

/**
* Get snap offset assuming that event is at center of shape.
*
* @param {Object} event - Event.
* @param {string} axis - Axis.
*
* @returns {number}
*/
function getSnapOffset(event, axis) {
var context = event.context,
shape = event.shape,
gridSnappingContext = context.gridSnappingContext || {},
snapLocation = gridSnappingContext.snapLocation;

if (!shape || !snapLocation) {
return 0;
}

if (axis === 'x') {
if (/left/.test(snapLocation)) {
return -shape.width / 2;
}

if (/right/.test(snapLocation)) {
return shape.width / 2;
}
} else {
if (/top/.test(snapLocation)) {
return -shape.height / 2;
}

if (/bottom/.test(snapLocation)) {
return shape.height / 2;
}
}

return 0;
}

function isHorizontal(axis) {
return axis === 'x';
}
Expand Down
20 changes: 16 additions & 4 deletions lib/features/move/Move.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {
assign,
filter,
groupBy
groupBy,
isObject
} from 'min-dash';

var LOW_PRIORITY = 500,
Expand Down Expand Up @@ -168,8 +169,19 @@ export default function MoveEvents(
return start(originalEvent, event.element);
});


function start(event, element, activate) {
/**
* Start move.
*
* @param {MouseEvent} event - Event.
* @param {djs.model.Shape} shape - Shape.
* @param {boolean} [activate] - Wether to automatically activate.
* @param {Object} [context] - Optional context.
*/
function start(event, element, activate, context) {
if (isObject(activate)) {
context = activate;
activate = false;
}

// do not move connections or the root element
if (element.waypoints || !element.parent) {
Expand All @@ -183,7 +195,7 @@ export default function MoveEvents(
autoActivate: activate,
data: {
shape: element,
context: {}
context: context || {}
}
});

Expand Down
Loading

0 comments on commit 2fd65f2

Please sign in to comment.