From 5bc6010d75c92dd911a49b2963224384e56d6cc7 Mon Sep 17 00:00:00 2001 From: Samuel Reed Date: Mon, 14 Jun 2021 21:15:52 -0400 Subject: [PATCH] fix(lockAspectRatio): make logic shorter and more accurate Added new tests to match --- __tests__/Resizable.test.js | 2 +- examples/ExampleLayout.js | 4 ++-- lib/Resizable.js | 19 ++++++++++--------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/__tests__/Resizable.test.js b/__tests__/Resizable.test.js index 19efa4b4..5a131bf3 100644 --- a/__tests__/Resizable.test.js +++ b/__tests__/Resizable.test.js @@ -288,7 +288,7 @@ describe('render Resizable', () => { describe('lockAspectRatio', () => { - [[5, 0], [0, 5]].forEach(([w, h]) => { + [[5, 0], [0, 5], [10, 5], [5, 10], [50, 51]].forEach(([w, h]) => { test(`drags with aspect ratio preserved w:${w} h:${h}`, () => { const element = shallow({resizableBoxChildren}); expect(props.onResize).not.toHaveBeenCalled(); diff --git a/examples/ExampleLayout.js b/examples/ExampleLayout.js index 27997ed3..37f85836 100644 --- a/examples/ExampleLayout.js +++ b/examples/ExampleLayout.js @@ -109,10 +109,10 @@ export default class ExampleLayout extends React.Component<{}, {width: number, h Resizable box with a handle that only appears on hover. - + Resizable square with a locked aspect ratio. - + Resizable rectangle with a locked aspect ratio. diff --git a/lib/Resizable.js b/lib/Resizable.js index be7e1e36..8dba8e0e 100644 --- a/lib/Resizable.js +++ b/lib/Resizable.js @@ -41,17 +41,18 @@ export default class Resizable extends React.Component { // If constraining to min and max, we need to also fit width and height to aspect ratio. if (lockAspectRatio) { - const resizingHorizontally = height === this.props.height; - if (resizingHorizontally) { - const ratio = this.props.width / this.props.height; + const ratio = this.props.width / this.props.height; + const deltaW = width - this.props.width; + const deltaH = height - this.props.height; + + // Find which coordinate was greater and should push the other toward it. + // E.g.: + // ratio = 1, deltaW = 10, deltaH = 5, deltaH should become 10. + // ratio = 2, deltaW = 10, deltaH = 6, deltaW should become 12. + if (Math.abs(deltaW) > Math.abs(deltaH * ratio)) { height = width / ratio; - width = height * ratio; } else { - // Take into account vertical resize with N/S handles on locked aspect - // ratio. Calculate the change height-first, instead of width-first - const ratio = this.props.height / this.props.width; - width = height / ratio; - height = width * ratio; + width = height * ratio; } }