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
|
// Don't allow a scale that results in an overall scale beyond min/max
|
||||||
// scale.
|
// scale.
|
||||||
final double currentScale = _transformationController.value.getMaxScaleOnAxis();
|
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(
|
final double clampedTotalScale = totalScale.clamp(
|
||||||
widget.minScale,
|
widget.minScale,
|
||||||
widget.maxScale,
|
widget.maxScale,
|
||||||
) as double;
|
) as double;
|
||||||
final double clampedScale = clampedTotalScale / currentScale;
|
final double clampedScale = clampedTotalScale / currentScale;
|
||||||
final Matrix4 nextMatrix = matrix.clone()..scale(clampedScale);
|
return 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 a new matrix representing the given matrix after applying the given
|
// Return a new matrix representing the given matrix after applying the given
|
||||||
|
@ -729,6 +729,47 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(transformationController.value.getMaxScaleOnAxis(), greaterThan(1.0));
|
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', () {
|
group('getNearestPointOnLine', () {
|
||||||
|
Loading…
Reference in New Issue
Block a user