interactjs
Version:
Drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE8+)
124 lines (99 loc) • 3.7 kB
JavaScript
// This module adds the options.resize.restrictEdges setting which sets min and
// max for the top, left, bottom and right edges of the target being resized.
//
// interact(target).resize({
// edges: { top: true, left: true },
// restrictEdges: {
// inner: { top: 200, left: 200, right: 400, bottom: 400 },
// outer: { top: 0, left: 0, right: 600, bottom: 600 },
// },
// });
const modifiers = require('./index');
const utils = require('../utils');
const rectUtils = require('../utils/rect');
const defaultOptions = require('../defaultOptions');
const resize = require('../actions/resize');
const { getRestrictionRect } = require('./restrict');
const noInner = { top: +Infinity, left: +Infinity, bottom: -Infinity, right: -Infinity };
const noOuter = { top: -Infinity, left: -Infinity, bottom: +Infinity, right: +Infinity };
const restrictEdges = {
defaults: {
enabled: false,
endOnly: false,
min: null,
max: null,
offset: null,
},
setOffset: function ({ interaction, startOffset, options }) {
if (!options) {
return utils.extend({}, startOffset);
}
const offset = getRestrictionRect(options.offset, interaction, interaction.startCoords.page);
if (offset) {
return {
top: startOffset.top + offset.y,
left: startOffset.left + offset.x,
bottom: startOffset.bottom + offset.y,
right: startOffset.right + offset.x,
};
}
return startOffset;
},
set: function ({ pageCoords, interaction, status, offset, options }) {
const edges = interaction.prepared.linkedEdges || interaction.prepared.edges;
if (!interaction.interacting() || !edges) {
return;
}
const page = status.useStatusXY
? { x: status.x, y: status.y }
: utils.extend({}, pageCoords);
const inner = rectUtils.xywhToTlbr(getRestrictionRect(options.inner, interaction, page)) || noInner;
const outer = rectUtils.xywhToTlbr(getRestrictionRect(options.outer, interaction, page)) || noOuter;
let modifiedX = page.x;
let modifiedY = page.y;
status.dx = 0;
status.dy = 0;
status.locked = false;
if (edges.top) {
modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);
}
else if (edges.bottom) {
modifiedY = Math.max(Math.min(outer.bottom - offset.bottom, page.y), inner.bottom - offset.bottom);
}
if (edges.left) {
modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);
}
else if (edges.right) {
modifiedX = Math.max(Math.min(outer.right - offset.right, page.x), inner.right - offset.right);
}
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 }) {
if (options && options.enabled
&& !(phase === 'start' && 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,
};
}
}
},
noInner,
noOuter,
getRestrictionRect,
};
modifiers.restrictEdges = restrictEdges;
modifiers.names.push('restrictEdges');
defaultOptions.perAction.restrictEdges = restrictEdges.defaults;
resize.defaults.restrictEdges = restrictEdges.defaults;
module.exports = restrictEdges;