interactjs
Version:
Drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE8+)
111 lines (85 loc) • 3.25 kB
JavaScript
const modifiers = require('./index');
const utils = require('../utils');
const defaultOptions = require('../defaultOptions');
const restrict = {
defaults: {
enabled : false,
endOnly : false,
restriction: null,
elementRect: null,
},
setOffset: function ({ rect, startOffset, options }) {
const elementRect = options && options.elementRect;
const offset = {};
if (rect && elementRect) {
offset.left = startOffset.left - (rect.width * elementRect.left);
offset.top = startOffset.top - (rect.height * elementRect.top);
offset.right = startOffset.right - (rect.width * (1 - elementRect.right));
offset.bottom = startOffset.bottom - (rect.height * (1 - elementRect.bottom));
}
else {
offset.left = offset.top = offset.right = offset.bottom = 0;
}
return offset;
},
set: function ({ pageCoords, interaction, status, options }) {
if (!options) { return status; }
const page = status.useStatusXY
? { x: status.x, y: status.y }
: utils.extend({}, pageCoords);
const restriction = getRestrictionRect(options.restriction, interaction, page);
if (!restriction) { return status; }
status.dx = 0;
status.dy = 0;
status.locked = false;
const rect = restriction;
let modifiedX = page.x;
let modifiedY = page.y;
const offset = interaction.modifierOffsets.restrict;
// object is assumed to have
// x, y, width, height or
// left, top, right, bottom
if ('x' in restriction && 'y' in restriction) {
modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right , page.x), rect.x + offset.left);
modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top );
}
else {
modifiedX = Math.max(Math.min(rect.right - offset.right , page.x), rect.left + offset.left);
modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top );
}
status.dx = modifiedX - page.x;
status.dy = modifiedY - page.y;
status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;
status.locked = !!(status.dx || status.dy);
status.modifiedX = modifiedX;
status.modifiedY = modifiedY;
},
modifyCoords: function ({ page, client, status, phase, options }) {
const elementRect = options && options.elementRect;
if (options && options.enabled
&& !(phase === 'start' && elementRect && status.locked)) {
if (status.locked) {
page.x += status.dx;
page.y += status.dy;
client.x += status.dx;
client.y += status.dy;
return {
dx: status.dx,
dy: status.dy,
};
}
}
},
getRestrictionRect,
};
function getRestrictionRect (value, interaction, page) {
if (utils.is.function(value)) {
return utils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]);
} else {
return utils.resolveRectLike(value, interaction.target, interaction.element);
}
}
modifiers.restrict = restrict;
modifiers.names.push('restrict');
defaultOptions.perAction.restrict = restrict.defaults;
module.exports = restrict;