Skip to content

Commit a298559

Browse files
committed
Fix flipRect flag not working
1 parent 20c6b42 commit a298559

File tree

5 files changed

+68
-27
lines changed

5 files changed

+68
-27
lines changed

packages/box_transform/lib/src/geometry.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,15 @@ class Box {
628628
/// Returns aspect ratio of this rectangle.
629629
double get aspectRatio => size.aspectRatio;
630630

631+
/// Returns aspect ratio of this rectangle. Unlike [aspectRatio], it has a
632+
/// safe mechanism where if the width or height is zero, returns 1.
633+
double get safeAspectRatio {
634+
if (size.width == 0 || size.height == 0) {
635+
return 1.0;
636+
}
637+
return size.aspectRatio;
638+
}
639+
631640
/// Whether the point specified by the given Vector2 (which is assumed to be
632641
/// relative to the origin) lies between the left and right and the top and
633642
/// bottom edges of this rectangle.

packages/box_transform/lib/src/helpers.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,9 @@ Box getClampingRectForCornerHandle({
442442
required Box availableArea,
443443
required HandlePosition handle,
444444
}) {
445-
final initialAspectRatio = initialRect.aspectRatio;
445+
final initialAspectRatio = initialRect.safeAspectRatio;
446446

447-
final double areaAspectRatio = availableArea.aspectRatio;
447+
final double areaAspectRatio = availableArea.safeAspectRatio;
448448

449449
double maxWidth;
450450
double maxHeight;
@@ -524,12 +524,12 @@ Box getMinRectForScaling({
524524
final double minHeight;
525525

526526
if (!constraints.isUnconstrained) {
527-
if (initialRect.aspectRatio < 1) {
527+
if (initialRect.safeAspectRatio < 1) {
528528
minWidth = constraints.minWidth;
529-
minHeight = minWidth / initialRect.aspectRatio;
529+
minHeight = minWidth / initialRect.safeAspectRatio;
530530
} else {
531531
minHeight = constraints.minHeight;
532-
minWidth = minHeight * initialRect.aspectRatio;
532+
minWidth = minHeight * initialRect.safeAspectRatio;
533533
}
534534
} else {
535535
minWidth = 0;

packages/box_transform/lib/src/transformer.dart

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class BoxTransformer {
128128
constraints: constraints,
129129
allowResizeOverflow: allowResizeOverflow,
130130
localPosition: localPosition,
131+
flipRect: flipRect,
131132
);
132133

133134
final Box newRect = result.rect;
@@ -190,6 +191,7 @@ class BoxTransformer {
190191
required HandlePosition handle,
191192
required Vector2 delta,
192193
required ResizeMode resizeMode,
194+
required bool flipRect,
193195
}) {
194196
double left;
195197
double top;
@@ -201,18 +203,40 @@ class BoxTransformer {
201203
right = initialBox.right + (handle.influencesRight ? delta.x : 0);
202204
bottom = initialBox.bottom + (handle.influencesBottom ? delta.y : 0);
203205

204-
final double width = (right - left).abs();
205-
final double height = (bottom - top).abs();
206+
double width = right - left;
207+
double height = bottom - top;
208+
209+
if (flipRect) {
210+
width = width.abs();
211+
height = height.abs();
212+
} else {
213+
// If not flipping, we need to make sure the width and height are
214+
// positive which would imply that the left and top are less than
215+
// the right and bottom respectively stopping rect from flipping.
216+
width = width.clamp(0, double.infinity);
217+
height = height.clamp(0, double.infinity);
218+
}
206219

207220
// If in symmetric scaling mode, utilize width and height to constructor
208221
// the new box from its center.
209222
if (resizeMode.hasSymmetry) {
223+
// symmetric resizing is not affected if flipping is disabled.
210224
final widthDelta = (initialBox.width - width) / 2;
211225
final heightDelta = (initialBox.height - height) / 2;
212226
left = initialBox.left + widthDelta;
213227
top = initialBox.top + heightDelta;
214228
right = initialBox.right - widthDelta;
215229
bottom = initialBox.bottom - heightDelta;
230+
} else if (!flipRect) {
231+
// If not flipping, then we know that handles are not allowed to
232+
// cross the opposite one. So we use handle with width and height
233+
// instead of left, top, right, bottom to construct the new box.
234+
return Box.fromHandle(
235+
handle.anchor(initialBox),
236+
handle,
237+
width,
238+
height,
239+
);
216240
}
217241

218242
return Box.fromLTRB(
@@ -233,6 +257,7 @@ class BoxTransformer {
233257
Constraints constraints = const Constraints.unconstrained(),
234258
bool allowResizeOverflow = true,
235259
required Vector2 localPosition,
260+
required bool flipRect,
236261
}) {
237262
// No constraints or clamping is done. Only delta is applied to the
238263
// initial box.
@@ -241,6 +266,7 @@ class BoxTransformer {
241266
handle: handle,
242267
delta: delta,
243268
resizeMode: resizeMode,
269+
flipRect: flipRect,
244270
);
245271

246272
InternalResizeResult result;
@@ -315,7 +341,7 @@ class BoxTransformer {
315341
//
316342
// final double newWidth;
317343
// final double newHeight;
318-
// final newAspectRatio = rect.width / rect.height;
344+
// final newAspectRatio = rect.safeAspectRatio;
319345
//
320346
// if (resizeMode.isScalable) {
321347
// if (newAspectRatio.abs() < aspectRatio.abs()) {
@@ -422,14 +448,14 @@ class BoxTransformer {
422448
constraints: constraints,
423449
);
424450

425-
final initialAspectRatio = initialRect.width / initialRect.height;
451+
final initialAspectRatio = initialRect.safeAspectRatio;
426452

427453
double rectWidth = rect.width;
428454
double rectHeight = rect.height;
429455

430456
final cursorRect = rect;
431457

432-
if (cursorRect.aspectRatio.abs() < initialAspectRatio.abs()) {
458+
if (cursorRect.safeAspectRatio.abs() < initialAspectRatio.abs()) {
433459
rectWidth = rectHeight * initialAspectRatio;
434460
} else {
435461
rectHeight = rectWidth / initialAspectRatio;
@@ -478,7 +504,7 @@ class BoxTransformer {
478504
Constraints constraints,
479505
Flip flip,
480506
) {
481-
final initialAspectRatio = initialRect.width / initialRect.height;
507+
final initialAspectRatio = initialRect.safeAspectRatio;
482508

483509
Box area = getAvailableAreaForHandle(
484510
rect: initialRect,
@@ -555,7 +581,7 @@ class BoxTransformer {
555581
Constraints constraints,
556582
Flip flip,
557583
) {
558-
final initialAspectRatio = initialRect.width / initialRect.height;
584+
final initialAspectRatio = initialRect.safeAspectRatio;
559585

560586
Box area = getAvailableAreaForHandle(
561587
rect: initialRect,
@@ -632,7 +658,7 @@ class BoxTransformer {
632658
Constraints constraints,
633659
Flip flip,
634660
) {
635-
final initialAspectRatio = initialRect.width / initialRect.height;
661+
final initialAspectRatio = initialRect.safeAspectRatio;
636662

637663
Box area = getAvailableAreaForHandle(
638664
rect: initialRect,
@@ -709,7 +735,7 @@ class BoxTransformer {
709735
Constraints constraints,
710736
Flip flip,
711737
) {
712-
final initialAspectRatio = initialRect.width / initialRect.height;
738+
final initialAspectRatio = initialRect.safeAspectRatio;
713739

714740
Box area = getAvailableAreaForHandle(
715741
rect: initialRect,
@@ -785,7 +811,7 @@ class BoxTransformer {
785811
HandlePosition handle,
786812
Constraints constraints,
787813
) {
788-
final initialAspectRatio = initialRect.width / initialRect.height;
814+
final initialAspectRatio = initialRect.safeAspectRatio;
789815

790816
final Box availableArea;
791817

@@ -811,7 +837,7 @@ class BoxTransformer {
811837
if (!constraints.isUnconstrained) {
812838
final double minWidth;
813839
final double minHeight;
814-
if (initialRect.aspectRatio > 1) {
840+
if (initialRect.safeAspectRatio > 1) {
815841
minHeight = constraints.minHeight;
816842
minWidth = minHeight * initialAspectRatio;
817843
} else {
@@ -836,7 +862,7 @@ class BoxTransformer {
836862

837863
final cursorRect = rect;
838864

839-
if (cursorRect.aspectRatio.abs() < initialAspectRatio.abs()) {
865+
if (cursorRect.safeAspectRatio.abs() < initialAspectRatio.abs()) {
840866
rectWidth = rectHeight * initialAspectRatio;
841867
} else {
842868
rectHeight = rectWidth / initialAspectRatio;
@@ -866,7 +892,7 @@ class BoxTransformer {
866892
HandlePosition handle,
867893
Constraints constraints,
868894
) {
869-
final initialAspectRatio = initialRect.width / initialRect.height;
895+
final initialAspectRatio = initialRect.safeAspectRatio;
870896

871897
final Box availableArea;
872898

@@ -892,7 +918,7 @@ class BoxTransformer {
892918
if (!constraints.isUnconstrained) {
893919
final double minWidth;
894920
final double minHeight;
895-
if (initialRect.aspectRatio > 1) {
921+
if (initialRect.safeAspectRatio > 1) {
896922
minHeight = constraints.minHeight;
897923
minWidth = minHeight * initialAspectRatio;
898924
} else {
@@ -961,14 +987,14 @@ class BoxTransformer {
961987
constraints: constraints,
962988
);
963989

964-
final initialAspectRatio = initialRect.width / initialRect.height;
990+
final initialAspectRatio = initialRect.safeAspectRatio;
965991

966992
double rectWidth = rect.width;
967993
double rectHeight = rect.height;
968994

969995
final cursorRect = rect;
970996

971-
if (cursorRect.aspectRatio.abs() < initialAspectRatio.abs()) {
997+
if (cursorRect.safeAspectRatio.abs() < initialAspectRatio.abs()) {
972998
rectWidth = rectHeight * initialAspectRatio;
973999
} else {
9741000
rectHeight = rectWidth / initialAspectRatio;
@@ -1032,14 +1058,14 @@ class BoxTransformer {
10321058
constraints: constraints,
10331059
);
10341060

1035-
final initialAspectRatio = initialRect.width / initialRect.height;
1061+
final initialAspectRatio = initialRect.safeAspectRatio;
10361062

10371063
double rectWidth = rect.width;
10381064
double rectHeight = rect.height;
10391065

10401066
final cursorRect = rect;
10411067

1042-
if (cursorRect.aspectRatio.abs() < initialAspectRatio.abs()) {
1068+
if (cursorRect.safeAspectRatio.abs() < initialAspectRatio.abs()) {
10431069
rectWidth = rectHeight * initialAspectRatio;
10441070
} else {
10451071
rectHeight = rectWidth / initialAspectRatio;
@@ -1103,14 +1129,14 @@ class BoxTransformer {
11031129
constraints: constraints,
11041130
);
11051131

1106-
final initialAspectRatio = initialRect.width / initialRect.height;
1132+
final initialAspectRatio = initialRect.safeAspectRatio;
11071133

11081134
double rectWidth = rect.width;
11091135
double rectHeight = rect.height;
11101136

11111137
final cursorRect = rect;
11121138

1113-
if (cursorRect.aspectRatio.abs() < initialAspectRatio.abs()) {
1139+
if (cursorRect.safeAspectRatio.abs() < initialAspectRatio.abs()) {
11141140
rectWidth = rectHeight * initialAspectRatio;
11151141
} else {
11161142
rectHeight = rectWidth / initialAspectRatio;

packages/flutter_box_transform/example/lib/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ class _ImageBoxState extends State<ImageBox> {
749749
cursorPosition: event.localPosition,
750750
clampingRect: model.clampingEnabled ? model.clampingRect : null,
751751
constraints: box.constraintsEnabled ? box.constraints : null,
752+
flipRect: box.flipRectWhileResizing,
752753
);
753754
},
754755
onResizeEnd: (event) {

packages/flutter_box_transform/example/lib/test_recorder.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class TestRecorder with ChangeNotifier {
3737
required Rect rect,
3838
required HandlePosition handle,
3939
required Offset cursorPosition,
40+
required bool flipRect,
4041
Rect? clampingRect,
4142
BoxConstraints? constraints,
4243
}) {
@@ -48,6 +49,7 @@ class TestRecorder with ChangeNotifier {
4849
position: cursorPosition,
4950
clampingBox: clampingRect,
5051
constraints: constraints,
52+
flipRect: flipRect,
5153
);
5254
current.add(TestRecord(action: action));
5355
return action;
@@ -98,6 +100,7 @@ class TestAction with EquatableMixin {
98100
final Offset position;
99101
final Rect? clampingBox;
100102
final BoxConstraints? constraints;
103+
final bool flipRect;
101104

102105
TestAction({
103106
required this.resizeMode,
@@ -107,6 +110,7 @@ class TestAction with EquatableMixin {
107110
required this.position,
108111
this.clampingBox,
109112
this.constraints,
113+
this.flipRect = false,
110114
}) : id = DateTime.now().millisecondsSinceEpoch;
111115

112116
@override
@@ -119,6 +123,7 @@ class TestAction with EquatableMixin {
119123
position,
120124
clampingBox,
121125
constraints,
126+
flipRect,
122127
];
123128
}
124129

@@ -383,7 +388,7 @@ class _TestRecorderUIState extends State<TestRecorderUI> {
383388
final StringBuffer buffer = StringBuffer();
384389

385390
String formattedValue(num value) {
386-
if(value.isInfinite) return 'double.infinity';
391+
if (value.isInfinite) return 'double.infinity';
387392
return roundValues ? value.round().toString() : value.toStringAsFixed(2);
388393
}
389394

@@ -420,7 +425,7 @@ class _TestRecorderUIState extends State<TestRecorderUI> {
420425
initialBox: Box.fromLTWH($left, $top, $width, $height),
421426
handle: ${record.action.handle},
422427
initialLocalPosition: Vector2(${formattedValue(record.action.position.dx)}, ${formattedValue(record.action.position.dy)}),
423-
flipRect: true,
428+
flipRect: ${record.action.flipRect},
424429
localPosition: Vector2(${formattedValue(record.localPosition!.dx)}, ${formattedValue(record.localPosition!.dy)}),
425430
${clampingRect != null ? 'clampingRect: $clampingRect,' : ''}
426431
${constraints != null ? 'constraints: $constraints,' : ''}

0 commit comments

Comments
 (0)