Skip to content

Commit b3f3915

Browse files
committed
fix: fit locked aspect ratio with least squares
1 parent ca33424 commit b3f3915

2 files changed

Lines changed: 9 additions & 14 deletions

File tree

__tests__/Resizable.test.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,13 @@ describe('render Resizable', () => {
390390
expect(props.onResize).not.toHaveBeenCalled();
391391
const seHandler = resizableRef.current.resizeHandler('onResize', 'se');
392392
seHandler(mockEvent, { node, deltaX: w, deltaY: h });
393+
const expected = 50 + (w + h) / 2;
393394
expect(props.onResize).toHaveBeenLastCalledWith(
394395
mockEvent,
395396
expect.objectContaining({
396397
size: {
397-
height: 50 + Math.max(w, h),
398-
width: 50 + Math.max(w, h),
398+
height: expected,
399+
width: expected,
399400
},
400401
})
401402
);

lib/Resizable.tsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,12 @@ export default class Resizable extends React.Component<Props, {}> {
4141
// If constraining to min and max, we need to also fit width and height to aspect ratio.
4242
if (lockAspectRatio) {
4343
const ratio = this.props.width / this.props.height;
44-
const deltaW = width - this.props.width;
45-
const deltaH = height - this.props.height;
46-
47-
// Find which coordinate was greater and should push the other toward it.
48-
// E.g.:
49-
// ratio = 1, deltaW = 10, deltaH = 5, deltaH should become 10.
50-
// ratio = 2, deltaW = 10, deltaH = 6, deltaW should become 12.
51-
if (Math.abs(deltaW) > Math.abs(deltaH * ratio)) {
52-
height = width / ratio;
53-
} else {
54-
width = height * ratio;
55-
}
44+
45+
// Project (width, height) onto the line w = ratio * h.
46+
// Distributes tracking error across both axes instead of forcing one to overshoot.
47+
// t = (w * ratio + h) / (ratio^2 + 1), new_w = t * ratio, new_h = t
48+
height = (width * ratio + height) / (ratio * ratio + 1);
49+
width = height * ratio;
5650
}
5751

5852
const [oldW, oldH] = [width, height];

0 commit comments

Comments
 (0)