Unverified Commit f78b27e4 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Fix InteractiveViewer minScale bug (#65432)

parent 551a2a6b
......@@ -646,26 +646,21 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
// Don't allow a scale that results in an overall scale beyond min/max
// scale.
final double currentScale = _transformationController.value.getMaxScaleOnAxis();
final double totalScale = currentScale * scale;
final double totalScale = math.max(
currentScale * scale,
// Ensure that the scale cannot make the child so big that it can't fit
// inside the boundaries (in either direction).
math.max(
_viewport.width / _boundaryRect.width,
_viewport.height / _boundaryRect.height,
),
);
final double clampedTotalScale = totalScale.clamp(
widget.minScale,
widget.maxScale,
) as double;
final double clampedScale = clampedTotalScale / currentScale;
final Matrix4 nextMatrix = matrix.clone()..scale(clampedScale);
// Ensure that the scale cannot make the child so big that it can't fit
// inside the boundaries (in either direction).
final double minScale = math.max(
_viewport.width / _boundaryRect.width,
_viewport.height / _boundaryRect.height,
);
if (clampedTotalScale < minScale) {
final double minCurrentScale = minScale / currentScale;
return matrix.clone()..scale(minCurrentScale);
}
return nextMatrix;
return matrix.clone()..scale(clampedScale);
}
// Return a new matrix representing the given matrix after applying the given
......
......@@ -729,6 +729,47 @@ void main() {
await tester.pumpAndSettle();
expect(transformationController.value.getMaxScaleOnAxis(), greaterThan(1.0));
});
// Regression test for https://github.com/flutter/flutter/issues/65304
testWidgets('can view beyond boundary when necessary for a small child', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: InteractiveViewer(
constrained: false,
minScale: 1.0,
maxScale: 1.0,
transformationController: transformationController,
child: const SizedBox(width: 200.0, height: 200.0),
),
),
),
),
);
expect(transformationController.value, equals(Matrix4.identity()));
// Pinch to zoom does nothing because minScale and maxScale are 1.0.
final Offset center = tester.getCenter(find.byType(SizedBox));
final Offset scaleStart1 = Offset(center.dx - 10.0, center.dy - 10.0);
final Offset scaleStart2 = Offset(center.dx + 10.0, center.dy + 10.0);
final Offset scaleEnd1 = Offset(center.dx - 20.0, center.dy - 20.0);
final Offset scaleEnd2 = Offset(center.dx + 20.0, center.dy + 20.0);
final TestGesture gesture = await tester.createGesture();
final TestGesture gesture2 = await tester.createGesture();
await gesture.down(scaleStart1);
await gesture2.down(scaleStart2);
await tester.pump();
await gesture.moveTo(scaleEnd1);
await gesture2.moveTo(scaleEnd2);
await tester.pump();
await gesture.up();
await gesture2.up();
await tester.pumpAndSettle();
expect(transformationController.value, equals(Matrix4.identity()));
});
});
group('getNearestPointOnLine', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment