mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix InteractiveViewer minScale bug (#65432)
This commit is contained in:
parent
551a2a6b69
commit
f78b27e41a
@ -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', () {
|
||||
|
Loading…
Reference in New Issue
Block a user