penguinmod-editor-2 / src /lib /drag-utils.js
soiz1's picture
Upload 2891 files
6bcb42f verified
/**
* @fileoverview
* Utility functions for drag interactions, e.g. sorting items in a grid/list.
*/
/**
* From an xy position and a list of boxes {top, left, bottom, right}, return there
* corresponding box index the position is over. The boxes are in a (possibly wrapped)
* list, the only requirement being all boxes are flush against the edges, that is,
* if they are along an outer edge, the position of that edge is identical.
* This functionality works for a single column of items, a wrapped list with
* many rows, or a single row of items.
* @param {{x: number, y: number}} position The xy coordinates to retreive the corresponding index of.
* @param {Array.<DOMRect>} boxes The rects of the items, returned from `getBoundingClientRect`
* @param {bool} isRtl are the boxes in RTL order.
* @return {?number} index of the corresponding box, or null if one could not be found.
*/
const indexForPositionOnList = ({x, y}, boxes, isRtl) => {
if (boxes.length === 0) return null;
let index = null;
const leftEdge = Math.min.apply(null, boxes.map(b => b.left));
const rightEdge = Math.max.apply(null, boxes.map(b => b.right));
const topEdge = Math.min.apply(null, boxes.map(b => b.top));
const bottomEdge = Math.max.apply(null, boxes.map(b => b.bottom));
for (let n = 0; n < boxes.length; n++) {
const box = boxes[n];
// Construct an "extended" box for each, extending out to infinity if
// the box is along a boundary.
let minX = box.left === leftEdge ? -Infinity : box.left;
let maxX = box.right === rightEdge ? Infinity : box.right;
const minY = box.top === topEdge ? -Infinity : box.top;
const maxY = box.bottom === bottomEdge ? Infinity : box.bottom;
// The last item in the wrapped list gets a right edge at infinity, even
// if it isn't the farthest right, in RTL mode. In LTR mode, it gets a
// left edge at infinity.
if (n === boxes.length - 1) {
if (isRtl) {
minX = -Infinity;
} else {
maxX = Infinity;
}
}
// Check if the point is in the bounds.
if (x >= minX && x <= maxX && y >= minY && y <= maxY) {
index = n;
break; // No need to keep looking.
}
}
return index;
};
export {
indexForPositionOnList
};