Skip to content

Commit 5bc6010

Browse files
committed
fix(lockAspectRatio): make logic shorter and more accurate
Added new tests to match
1 parent 8b99980 commit 5bc6010

File tree

3 files changed

+13
-12
lines changed

3 files changed

+13
-12
lines changed

__tests__/Resizable.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ describe('render Resizable', () => {
288288

289289
describe('lockAspectRatio', () => {
290290

291-
[[5, 0], [0, 5]].forEach(([w, h]) => {
291+
[[5, 0], [0, 5], [10, 5], [5, 10], [50, 51]].forEach(([w, h]) => {
292292
test(`drags with aspect ratio preserved w:${w} h:${h}`, () => {
293293
const element = shallow(<Resizable {...customProps} lockAspectRatio={true}>{resizableBoxChildren}</Resizable>);
294294
expect(props.onResize).not.toHaveBeenCalled();

examples/ExampleLayout.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,10 @@ export default class ExampleLayout extends React.Component<{}, {width: number, h
109109
<ResizableBox className="box hover-handles" width={200} height={200} minConstraints={[150, 150]} maxConstraints={[500, 300]}>
110110
<span className="text">Resizable box with a handle that only appears on hover.</span>
111111
</ResizableBox>
112-
<ResizableBox className="box" width={200} height={200} lockAspectRatio={true}>
112+
<ResizableBox className="box" width={200} height={200} lockAspectRatio={true} resizeHandles={['sw', 'se', 'nw', 'ne', 'w', 'e', 'n', 's']}>
113113
<span className="text">Resizable square with a locked aspect ratio.</span>
114114
</ResizableBox>
115-
<ResizableBox className="box" width={200} height={120} lockAspectRatio={true}>
115+
<ResizableBox className="box" width={200} height={120} lockAspectRatio={true} resizeHandles={['sw', 'se', 'nw', 'ne', 'w', 'e', 'n', 's']}>
116116
<span className="text">Resizable rectangle with a locked aspect ratio.</span>
117117
</ResizableBox>
118118
<ResizableBox className="box" width={200} height={200} axis="x">

lib/Resizable.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,18 @@ export default class Resizable extends React.Component<Props, void> {
4141

4242
// If constraining to min and max, we need to also fit width and height to aspect ratio.
4343
if (lockAspectRatio) {
44-
const resizingHorizontally = height === this.props.height;
45-
if (resizingHorizontally) {
46-
const ratio = this.props.width / this.props.height;
44+
const ratio = this.props.width / this.props.height;
45+
const deltaW = width - this.props.width;
46+
const deltaH = height - this.props.height;
47+
48+
// Find which coordinate was greater and should push the other toward it.
49+
// E.g.:
50+
// ratio = 1, deltaW = 10, deltaH = 5, deltaH should become 10.
51+
// ratio = 2, deltaW = 10, deltaH = 6, deltaW should become 12.
52+
if (Math.abs(deltaW) > Math.abs(deltaH * ratio)) {
4753
height = width / ratio;
48-
width = height * ratio;
4954
} else {
50-
// Take into account vertical resize with N/S handles on locked aspect
51-
// ratio. Calculate the change height-first, instead of width-first
52-
const ratio = this.props.height / this.props.width;
53-
width = height / ratio;
54-
height = width * ratio;
55+
width = height * ratio;
5556
}
5657
}
5758

0 commit comments

Comments
 (0)