Flutter:将图像保持在屏幕边界内按比例和平移
Flutter: keep image within the screen borders on scale and pan
我正在尝试通过双击和缩放在图像上实现缩放 in\out,但我发现每当我缩放图像时 - 图像能够部分“走出”屏幕并且背景填充 space 左侧...(请参阅下面当前应用状态的屏幕截图)。我尝试包装一些其他小部件并更改图像的 fit
属性,但它没有产生任何结果。
我希望图像始终适合屏幕边界,尤其是在缩放时。我错过了什么?如何使图像在缩放或平移时不“滑动”到屏幕边界之外?
Screenshot of app's current state,其中空的space用黄色标示
我的代码:
///controllers and details variable for zoom on double tap
final _transformationController = TransformationController();
TapDownDetails _doubleTapDetails;
///dismiss thresholds for an image to be dimissed
final Map<DismissDirection, double> _dismissThresholds = {
DismissDirection.horizontal: 0.8,
DismissDirection.vertical: 0.6
};
///big circular progress indicator
final Center _circularProgressIndicator = Center(
child: SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightGreen[800]),
)
),
);
void _handleDoubleTapDown(TapDownDetails details) {
_doubleTapDetails = details;
}
void _handleDoubleTap() {
if (_transformationController.value != Matrix4.identity()) {
_transformationController.value = Matrix4.identity();
} else {
final position = _doubleTapDetails.localPosition;
/// Fox a 2x zoom:
_transformationController.value = Matrix4.identity()
..translate(-position.dx, -position.dy)
..scale(2.0);
}
}
@override
Widget build(BuildContext context) {
return Center(
child: Dismissible(
key: const Key('key2'),
dismissThresholds: _dismissThresholds,
confirmDismiss: (direction) {
return Future<bool>(() => _transformationController.value.isIdentity());
},
direction: DismissDirection.horizontal,
onDismissed: (_) {print ('dismissed horiz.')},
child: Dismissible(
dismissThresholds: _dismissThresholds,
key: const Key('key'),
confirmDismiss: (direction) {
return Future<bool>(() => _transformationController.value.isIdentity());
},
direction: DismissDirection.vertical,
onDismissed: (_) {print ('dismissed vert.')},
child: GestureDetector(
onDoubleTapDown: _handleDoubleTapDown,
onDoubleTap: _handleDoubleTap,
child: InteractiveViewer(
transformationController: _transformationController,
minScale: 1.0,
maxScale: 2.0,
panEnabled: true,
scaleEnabled: true,
boundaryMargin: EdgeInsets.all(100.0),
child: CachedNetworkImage(
imageUrl: 'https://cdn.onlinewebfonts.com/svg/img_258083.png',
placeholder: (context, url) => _circularProgressIndicator,
fit: BoxFit.fitWidth,
alignment: FractionalOffset.center,
)
),
),
),
)
);
}
我通过设置
boundaryMargin:
到 EdgeInsets.all(0.0),
在 InteractiveViewer
下
我正在尝试通过双击和缩放在图像上实现缩放 in\out,但我发现每当我缩放图像时 - 图像能够部分“走出”屏幕并且背景填充 space 左侧...(请参阅下面当前应用状态的屏幕截图)。我尝试包装一些其他小部件并更改图像的 fit
属性,但它没有产生任何结果。
我希望图像始终适合屏幕边界,尤其是在缩放时。我错过了什么?如何使图像在缩放或平移时不“滑动”到屏幕边界之外?
Screenshot of app's current state,其中空的space用黄色标示
我的代码:
///controllers and details variable for zoom on double tap
final _transformationController = TransformationController();
TapDownDetails _doubleTapDetails;
///dismiss thresholds for an image to be dimissed
final Map<DismissDirection, double> _dismissThresholds = {
DismissDirection.horizontal: 0.8,
DismissDirection.vertical: 0.6
};
///big circular progress indicator
final Center _circularProgressIndicator = Center(
child: SizedBox(
width: 60,
height: 60,
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightGreen[800]),
)
),
);
void _handleDoubleTapDown(TapDownDetails details) {
_doubleTapDetails = details;
}
void _handleDoubleTap() {
if (_transformationController.value != Matrix4.identity()) {
_transformationController.value = Matrix4.identity();
} else {
final position = _doubleTapDetails.localPosition;
/// Fox a 2x zoom:
_transformationController.value = Matrix4.identity()
..translate(-position.dx, -position.dy)
..scale(2.0);
}
}
@override
Widget build(BuildContext context) {
return Center(
child: Dismissible(
key: const Key('key2'),
dismissThresholds: _dismissThresholds,
confirmDismiss: (direction) {
return Future<bool>(() => _transformationController.value.isIdentity());
},
direction: DismissDirection.horizontal,
onDismissed: (_) {print ('dismissed horiz.')},
child: Dismissible(
dismissThresholds: _dismissThresholds,
key: const Key('key'),
confirmDismiss: (direction) {
return Future<bool>(() => _transformationController.value.isIdentity());
},
direction: DismissDirection.vertical,
onDismissed: (_) {print ('dismissed vert.')},
child: GestureDetector(
onDoubleTapDown: _handleDoubleTapDown,
onDoubleTap: _handleDoubleTap,
child: InteractiveViewer(
transformationController: _transformationController,
minScale: 1.0,
maxScale: 2.0,
panEnabled: true,
scaleEnabled: true,
boundaryMargin: EdgeInsets.all(100.0),
child: CachedNetworkImage(
imageUrl: 'https://cdn.onlinewebfonts.com/svg/img_258083.png',
placeholder: (context, url) => _circularProgressIndicator,
fit: BoxFit.fitWidth,
alignment: FractionalOffset.center,
)
),
),
),
)
);
}
我通过设置
boundaryMargin:
到 EdgeInsets.all(0.0),
在 InteractiveViewer