Skip to content

Commit 03a9b48

Browse files
committed
Added lockAspectRatio option, fixes #3
1 parent eba6930 commit 03a9b48

File tree

4 files changed

+52
-12
lines changed

4 files changed

+52
-12
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ render: function() {
3434

3535

3636
### Options
37-
38-
```javascript
37+
{
3938
// Functions
4039
onResizeStop: React.PropTypes.func,
4140
onResizeStart: React.PropTypes.func,
@@ -47,4 +46,5 @@ height: React.PropTypes.number.isRequired,
4746
handleSize: React.PropTypes.array,
4847
// These will be passed wholesale to react-draggable
4948
draggableOpts: React.PropTypes.object
49+
}
5050
```

lib/Resizable.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ var Resizable = module.exports = React.createClass({
3232
},
3333

3434
minConstraints() {
35-
return parseConstraints(this.props.minConstraints, this.props.handleSize[0]) || this.props.handleSize;
35+
return parseConstraints(this.props.minConstraints, this.props.handleSize) || this.props.handleSize;
3636
},
3737

3838
maxConstraints() {
39-
return parseConstraints(this.props.maxConstraints, this.props.handleSize[1]);
39+
return parseConstraints(this.props.maxConstraints, this.props.handleSize);
4040
},
4141

4242

@@ -101,7 +101,7 @@ function calcWH({left, top}, handleSize) {
101101
*/
102102
function parseConstraints(constraints, handleSize) {
103103
if (!constraints) return;
104-
return constraints.map(function(c) {
105-
return c - handleSize;
104+
return constraints.map(function(c, i) {
105+
return c - handleSize[i];
106106
});
107107
}

lib/ResizableBox.jsx

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,56 @@ var ResizableBox = module.exports = React.createClass({
99
mixins: [PureRenderMixin],
1010

1111
propTypes: {
12+
lockAspectRatio: React.PropTypes.bool
13+
},
14+
15+
getDefaultProps() {
16+
return {
17+
lockAspectRatio: false,
18+
handleSize: [20,20],
19+
minConstraints: [20,20]
20+
};
1221
},
1322

1423
getInitialState() {
1524
return {
1625
width: this.props.width,
17-
height: this.props.height
26+
height: this.props.height,
27+
aspectRatio: this.props.width / this.props.height
1828
};
1929
},
2030

2131
onResize(event, {element, size}) {
22-
if (size.width !== this.state.width || size.height !== this.state.height) {
23-
this.setState({
24-
width: size.width,
25-
height: size.height
26-
});
32+
var {width, height} = size;
33+
var widthChanged = width !== this.state.width, heightChanged = height !== this.state.height;
34+
if (!widthChanged && !heightChanged) return;
35+
36+
if (this.props.lockAspectRatio) {
37+
[width, height] = this.preserveAspectRatio(width, height);
38+
}
39+
40+
this.setState({
41+
width: width,
42+
height: height
43+
});
44+
},
45+
46+
// If you do this, be careful of constraints
47+
preserveAspectRatio(width, height) {
48+
var [min, max] = [this.props.minConstraints, this.props.maxConstraints];
49+
50+
height = width / this.state.aspectRatio;
51+
width = height * this.state.aspectRatio;
52+
53+
if (min) {
54+
width = Math.max(min[0], width);
55+
height = Math.max(min[1], height);
56+
}
57+
if (max) {
58+
width = Math.min(max[0], width);
59+
height = Math.min(max[1], height);
2760
}
61+
return [width, height];
2862
},
2963

3064
render() {

test/TestLayout.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ var TestLayout = module.exports = React.createClass({
2424
<ResizableBox className="box box3" width={200} height={200} minConstraints={[150, 150]} maxConstraints={[500, 300]}>
2525
<span className="text">Resizable box with a handle that only appears on hover.</span>
2626
</ResizableBox>
27+
<ResizableBox className="box" width={200} height={200} lockAspectRatio={true}>
28+
<span className="text">Resizable square with a locked aspect ratio.</span>
29+
</ResizableBox>
30+
<ResizableBox className="box" width={200} height={120} lockAspectRatio={true}>
31+
<span className="text">Resizable rectangle with a locked aspect ratio.</span>
32+
</ResizableBox>
2733
</div>
2834
);
2935
}

0 commit comments

Comments
 (0)