mirror of
https://github.com/captbaritone/webamp.git
synced 2026-08-03 23:43:28 +00:00
Fix snapping for non-overlapping boxes
Boxes were snapping together even if they were not overlapping in the
non-snapping axis:
###
#A#
###
###
#B#
###
Although A and B are near eachother on the X axis they should not snap
together, since they are far apart on the Y axis. Now they don't.
This commit is contained in:
parent
299b4cac77
commit
9dde8dfc9c
2 changed files with 81 additions and 12 deletions
|
|
@ -6,7 +6,9 @@ import {
|
|||
left,
|
||||
right,
|
||||
near,
|
||||
snap
|
||||
snap,
|
||||
overlapY,
|
||||
overlapX
|
||||
} from '../snapUtils';
|
||||
|
||||
describe('side functions', () => {
|
||||
|
|
@ -46,6 +48,51 @@ describe('near function', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('overlap functions', () => {
|
||||
it('overlapY detects when the boxes overlap in the Y axis', () => {
|
||||
const a = {y: 10, height: 50};
|
||||
const b = {y: 40, height: 50};
|
||||
const actual = overlapY(a, b);
|
||||
const expected = true;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('overlapY detects when the boxes are within SNAP_DISTANCE on the Y axis', () => {
|
||||
const a = {y: 10, height: 50};
|
||||
const b = {y: 70, height: 50};
|
||||
const actual = overlapY(a, b);
|
||||
const expected = true;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('overlapY detects when the boxes do not overlap in the Y axis', () => {
|
||||
const a = {y: 10, height: 50};
|
||||
const b = {y: 90, height: 50};
|
||||
const actual = overlapY(a, b);
|
||||
const expected = false;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('overlapX detects when the boxes overlap in the X axis', () => {
|
||||
const a = {x: 10, width: 50};
|
||||
const b = {x: 40, width: 50};
|
||||
const actual = overlapX(a, b);
|
||||
const expected = true;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('overlapX detects when the boxes are within SNAP_DISTANCE on the X axis', () => {
|
||||
const a = {x: 10, width: 50};
|
||||
const b = {x: 70, width: 50};
|
||||
const actual = overlapX(a, b);
|
||||
const expected = true;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('overlapX detects when the boxes do not overlap in the X axis', () => {
|
||||
const a = {x: 10, width: 50};
|
||||
const b = {x: 90, width: 50};
|
||||
const actual = overlapX(a, b);
|
||||
const expected = false;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('snap function', () => {
|
||||
it('does not snap if A and B are obviously far apart', () => {
|
||||
const a = {x: 10, y: 10, width: 100, height: 100};
|
||||
|
|
@ -82,4 +129,18 @@ describe('snap function', () => {
|
|||
const expected = {y: 110};
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('does not snap to the X axis if A is below B', () => {
|
||||
const a = {x: 10, y: 10, width: 100, height: 100};
|
||||
const b = {x: 110, y: 150, width: 100, height: 100};
|
||||
const actual = snap(a, b);
|
||||
const expected = {};
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
it('snaps in both axis if the corners are within SNAP_DISTANCE', () => {
|
||||
const a = {x: 10, y: 10, width: 100, height: 100};
|
||||
const b = {x: 120, y: 120, width: 100, height: 100};
|
||||
const actual = snap(a, b);
|
||||
const expected = {x: 20, y: 20};
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,23 +9,31 @@ 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) => left(a) <= right(b) + SNAP_DISTANCE && left(b) <= right(a) + SNAP_DISTANCE;
|
||||
export const overlapY = (a, b) => top(a) <= bottom(b) + SNAP_DISTANCE && top(b) <= bottom(a) + SNAP_DISTANCE;
|
||||
|
||||
export const snap = (boxA, boxB) => {
|
||||
let x, y;
|
||||
|
||||
if (near(left(boxA), right(boxB))) {
|
||||
x = right(boxB);
|
||||
if (overlapY(boxA, boxB)) {
|
||||
if (near(left(boxA), right(boxB))) {
|
||||
x = right(boxB);
|
||||
}
|
||||
|
||||
if (near(right(boxA), left(boxB))) {
|
||||
x = left(boxB) - boxA.width;
|
||||
}
|
||||
}
|
||||
|
||||
if (near(right(boxA), left(boxB))) {
|
||||
x = left(boxB) - boxA.width;
|
||||
}
|
||||
if (overlapX(boxA, boxB)) {
|
||||
if (near(top(boxA), bottom(boxB))) {
|
||||
y = bottom(boxB);
|
||||
}
|
||||
|
||||
if (near(top(boxA), bottom(boxB))) {
|
||||
y = bottom(boxB);
|
||||
}
|
||||
|
||||
if (near(bottom(boxA), top(boxB))) {
|
||||
y = top(boxB) - boxA.height;
|
||||
if (near(bottom(boxA), top(boxB))) {
|
||||
y = top(boxB) - boxA.height;
|
||||
}
|
||||
}
|
||||
return {x, y};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue