Initial commit of 001code-html Scratch frontend project.
Includes scratch-gui, scratch-vm, scratch-blocks, scratch-render, scratch-l10n, and deployment config. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
55
scratch-gui/src/lib/drag-utils.js
Normal file
55
scratch-gui/src/lib/drag-utils.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @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
|
||||
};
|
||||
Reference in New Issue
Block a user