mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-24 02:36:00 +00:00
88 lines
2.2 KiB
JavaScript
88 lines
2.2 KiB
JavaScript
// box = {x, y, width, height}
|
|
|
|
export const SNAP_DISTANCE = 15;
|
|
|
|
export const top = (box) => box.y;
|
|
export const bottom = (box) => box.y + box.height;
|
|
export const left = (box) => box.x;
|
|
export const right = (box) => box.x + box.width;
|
|
|
|
export const near = (a, b) => Math.abs(a - b) < SNAP_DISTANCE;
|
|
|
|
// http://stackoverflow.com/a/3269471/1263117
|
|
export const overlapX = (a, b) => {
|
|
return left(a) <= right(b) + SNAP_DISTANCE &&
|
|
left(b) <= right(a) + SNAP_DISTANCE;
|
|
};
|
|
export const overlapY = (a, b) => {
|
|
return top(a) <= bottom(b) + SNAP_DISTANCE &&
|
|
top(b) <= bottom(a) + SNAP_DISTANCE;
|
|
};
|
|
|
|
export const snap = (boxA, boxB) => {
|
|
let x, y;
|
|
|
|
// TODO: Refactor/simplify this code
|
|
if (overlapY(boxA, boxB)) {
|
|
if (near(left(boxA), right(boxB))) {
|
|
x = right(boxB);
|
|
} else if (near(right(boxA), left(boxB))) {
|
|
x = left(boxB) - boxA.width;
|
|
} else if (near(left(boxA), left(boxB))) {
|
|
x = left(boxB);
|
|
} else if (near(right(boxA), right(boxB))) {
|
|
x = right(boxB) - boxA.width;
|
|
}
|
|
}
|
|
|
|
if (overlapX(boxA, boxB)) {
|
|
if (near(top(boxA), bottom(boxB))) {
|
|
y = bottom(boxB);
|
|
} else if (near(bottom(boxA), top(boxB))) {
|
|
y = top(boxB) - boxA.height;
|
|
} else if (near(top(boxA), top(boxB))) {
|
|
y = top(boxB);
|
|
} else if (near(bottom(boxA), bottom(boxB))) {
|
|
y = bottom(boxB) - boxA.height;
|
|
}
|
|
}
|
|
return {x, y};
|
|
};
|
|
|
|
export const snapToMany = (boxA, otherBoxes) => {
|
|
let x, y;
|
|
|
|
otherBoxes.forEach((boxB) => {
|
|
const newPos = snap(boxA, boxB);
|
|
x = newPos.x || x;
|
|
y = newPos.y || y;
|
|
});
|
|
|
|
return {x, y};
|
|
};
|
|
|
|
export const snapWithin = (boxA, boundingBox) => {
|
|
let x, y;
|
|
|
|
if (boxA.x - SNAP_DISTANCE < 0) {
|
|
x = 0;
|
|
} else if ((boxA.x + boxA.width + SNAP_DISTANCE) > boundingBox.width) {
|
|
x = boundingBox.width - boxA.width;
|
|
}
|
|
|
|
if (boxA.y - SNAP_DISTANCE < 0) {
|
|
y = 0;
|
|
} else if ((boxA.y + boxA.height + SNAP_DISTANCE) > boundingBox.height) {
|
|
y = boundingBox.height - boxA.height;
|
|
}
|
|
|
|
return {x, y};
|
|
};
|
|
|
|
export const applySnap = (original, ...snaps) => (
|
|
snaps.reduce((previous, snapped) => ({
|
|
...previous,
|
|
x: typeof snapped.x !== 'undefined' ? snapped.x : previous.x,
|
|
y: typeof snapped.y !== 'undefined' ? snapped.y : previous.y
|
|
}), original)
|
|
);
|