Skip to content

Commit 915613d

Browse files
authored
Fix calcXY calculation (react-grid-layout#2059)
1 parent 9129bee commit 915613d

File tree

4 files changed

+28
-42
lines changed

4 files changed

+28
-42
lines changed

lib/GridItem.jsx

+3-16
Original file line numberDiff line numberDiff line change
@@ -519,14 +519,7 @@ export default class GridItem extends React.Component<Props, State> {
519519
this.setState({ dragging: newPosition });
520520

521521
// Call callback with this data
522-
const { containerPadding } = this.props;
523-
const { x, y } = calcXY(
524-
positionParams,
525-
top - containerPadding[1],
526-
left - containerPadding[0],
527-
w,
528-
h
529-
);
522+
const { x, y } = calcXY(positionParams, top, left, w, h);
530523
return onDrag.call(this, i, x, y, {
531524
e,
532525
node,
@@ -546,18 +539,12 @@ export default class GridItem extends React.Component<Props, State> {
546539
if (!this.state.dragging) {
547540
throw new Error("onDragEnd called before onDragStart.");
548541
}
549-
const { w, h, i, containerPadding } = this.props;
542+
const { w, h, i } = this.props;
550543
const { left, top } = this.state.dragging;
551544
const newPosition: PartialPosition = { top, left };
552545
this.setState({ dragging: null });
553546

554-
const { x, y } = calcXY(
555-
this.getPositionParams(),
556-
top - containerPadding[1],
557-
left - containerPadding[0],
558-
w,
559-
h
560-
);
547+
const { x, y } = calcXY(this.getPositionParams(), top, left, w, h);
561548

562549
return onDragStop.call(this, i, x, y, {
563550
e,

lib/calculateUtils.js

+6-10
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,14 @@ export function calcXY(
105105
w: number,
106106
h: number
107107
): { x: number, y: number } {
108-
const { margin, cols, rowHeight, maxRows } = positionParams;
108+
const { margin, containerPadding, cols, rowHeight, maxRows } = positionParams;
109109
const colWidth = calcGridColWidth(positionParams);
110110

111-
// left = colWidth * x + margin * (x + 1)
112-
// l = cx + m(x+1)
113-
// l = cx + mx + m
114-
// l - m = cx + mx
115-
// l - m = x(c + m)
116-
// (l - m) / (c + m) = x
117-
// x = (left - margin) / (coldWidth + margin)
118-
let x = Math.round((left - margin[0]) / (colWidth + margin[0]));
119-
let y = Math.round((top - margin[1]) / (rowHeight + margin[1]));
111+
// left = containerPaddingX + x * (colWidth + marginX)
112+
// x * (colWidth + marginX) = left - containerPaddingX
113+
// x = (left - containerPaddingX) / (colWidth + marginX)
114+
let x = Math.round((left - containerPadding[0]) / (colWidth + margin[0]));
115+
let y = Math.round((top - containerPadding[1]) / (rowHeight + margin[1]));
120116

121117
// Capping
122118
x = clamp(x, 0, cols - w);

test/spec/lifecycle-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,14 @@ describe("Lifecycle tests", function () {
375375
expect(gridLayout.state("droppingDOMNode")).toEqual(null);
376376

377377
// Drag the droppable over the grid layout.
378-
dragDroppableTo(wrapper, 200, 150);
378+
dragDroppableTo(wrapper, 200, 140);
379379

380380
// We should have the position in our state.
381381
expect(gridLayout.state("droppingPosition")).toHaveProperty(
382382
"left",
383383
200
384384
);
385-
expect(gridLayout.state("droppingPosition")).toHaveProperty("top", 150);
385+
expect(gridLayout.state("droppingPosition")).toHaveProperty("top", 140);
386386
// We should now have the placeholder element in our state.
387387
expect(gridLayout.state("droppingDOMNode")).toHaveProperty(
388388
"type",

test/spec/utils-test.js

+17-14
Original file line numberDiff line numberDiff line change
@@ -657,35 +657,38 @@ describe("calcWH", () => {
657657

658658
describe("calcXY", () => {
659659
const mockPositionParams = {
660-
margin: [0, 0],
661-
containerPadding: [0, 0],
662-
containerWidth: 500,
660+
margin: [20, 20],
661+
containerPadding: [50, 50],
662+
containerWidth: 560,
663663
cols: 4,
664664
rowHeight: 100,
665665
maxRows: 3
666666
};
667667

668668
it("return {x:0, y:0}", () => {
669-
const TOP = 10;
670-
const LEFT = 10;
671-
const W = 300;
672-
const H = 100;
669+
// Midpoint between x=0 and x=1 is at 110
670+
const LEFT = 109;
671+
const TOP = 100;
672+
const W = 1;
673+
const H = 1;
673674
const res = calcXY(mockPositionParams, TOP, LEFT, W, H);
674675
expect(JSON.stringify(res)).toBe(JSON.stringify({ x: 0, y: 0 }));
675676
});
676677
it("return {x:1, y:0}", () => {
678+
// Midpoint between x=0 and x=1 is at 110
679+
const LEFT = 111;
677680
const TOP = 0;
678-
const LEFT = 100;
679-
const W = 0;
680-
const H = 0;
681+
const W = 1;
682+
const H = 1;
681683
const res = calcXY(mockPositionParams, TOP, LEFT, W, H);
682684
expect(JSON.stringify(res)).toBe(JSON.stringify({ x: 1, y: 0 }));
683685
});
684686
it("return {x:0, y:1}", () => {
685-
const TOP = 110;
686-
const LEFT = 0;
687-
const W = 0;
688-
const H = 0;
687+
// Midpoint of x=0, y=1 is at (100, 220)
688+
const LEFT = 50;
689+
const TOP = 170;
690+
const W = 1;
691+
const H = 1;
689692
const res = calcXY(mockPositionParams, TOP, LEFT, W, H);
690693
expect(JSON.stringify(res)).toBe(JSON.stringify({ x: 0, y: 1 }));
691694
});

0 commit comments

Comments
 (0)