My question essentially duplicates the previously asked question: Flutter: How to set a max/min scale using matrix_gesture_detector
I have a MatrixGestureDetector:
MatrixGestureDetector(
onMatrixUpdate: (m, tm, sm, rm) {
setState(() {
transform = m;
});
},
child: Transform(
transform: transform,
child: Image.asset("assets/maps/map.gif"),
),
),
The picture can be zoomed in and out indefinitely, but I want to limit the minimum and maximum scale.
The solution suggested in the link above is not correct for me. The scale is really limited, but when it reaches its limits, gestures start to be handled incorrectly. The picture starts moving very quickly when you try to zoom in or out when the limits are reached.
Is there any solution to this problem? Maybe there are other packages to solve my problem? PhotoViev did not satisfy me for the reason described here: Flutter PhotoView - Rotation about the point between the fingers
Flutter announced a new version(1.20) and it came with a new widget called InteractiveViewer
.
You can use the InteractiveViewer
to achieve what you want by setting a minScale
and maxScale
.
This release introduces a new widget, the
InteractiveViewer
. TheInteractiveViewer
is designed for building common kinds of interactivity into your app, like pan, zoom, and drag ’n’ drop
Read more about the release here: Flutter 1.20 Release notes
I added a demo:
NOTE: You can only use this widget if you have upgraded to the latest Flutter version
(1.20)
class ZoomImage extends StatelessWidget {
final transformationController = TransformationController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: InteractiveViewer(
transformationController: transformationController,
onInteractionEnd: (details) {
setState(() {
// unzoom when interaction has ended
transformationController.toScene(Offset.zero);
});
},
// set the boundary margin for the image
boundaryMargin: EdgeInsets.all(20.0),
// set min scale here
minScale: 0.1,
// set maximum scall here
maxScale: 1.6,
child: ClipRRect(
borderRadius: BorderRadius.circular(18.0),
child: Image.asset('assets/maps/map.gif'),
),
),
);
}
}