我有一个保存图像的InteractiveViewer小部件。
我如何使用InteractiveViewer缩放TransformationController,以便当用户点击按钮时,InteractiveViewer会放大到InteractiveViewer当前中心的任意缩放级别?
我试过用
final currentScale = _transformationController.value.getMaxScaleOnAxis();
_transformationController.value = Matrix4.identity()..scale(currentScale * 1.1);
虽然这放大了预期,但它将当前位置重置到InteractiveViewer的左上角,这不是我想要的。
我的预期行为是,视图不会重置到左上角,而是在当前可见的视图中心放大。
发布于 2022-11-18 10:20:29
我设法解决了我的问题。对@pskink和我的同事大吼大叫。此实现将根据当前位置放大。
final x = Offset(constraints.maxWidth / 2, constraints.maxHeight / 2);
final offset1 = _transformationController.toScene(x);
_transformationController.value.scale(1.1);
final offset2 = _transformationController.toScene(x);
final dx = offset1.dx - offset2.dx;
final dy = offset1.dy - offset2.dy;
_transformationController.value.translate(-dx, -dy);
constraints.maxWidth
和constraints.maxHeight
来自围绕InteractiveViewer
小部件的LayoutBuilder
。
下面是@pskink在中心放大的实现:
class FooMatic extends StatefulWidget {
const FooMatic({Key? key}) : super(key: key);
@override
State<FooMatic> createState() => _FooMaticState();
}
class _FooMaticState extends State<FooMatic> with TickerProviderStateMixin {
TransformationController ctrl = TransformationController();
late Size size;
late AnimationController animationCtrl = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 800),
);
@override
void initState() {
super.initState();
animationCtrl.addListener(_animationTick);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
ElevatedButton(onPressed: animationCtrl.forward, child: const Text('zoom in')),
ElevatedButton(onPressed: animationCtrl.reverse, child: const Text('zoom out')),
],
),
Expanded(
child: LayoutBuilder(
builder: (context, constraints) {
size = constraints.biggest;
return Stack(
children: [
InteractiveViewer(
transformationController: ctrl,
constrained: false,
child: const FlutterLogo(size: 1000),
),
Center(
child: Container(
width: 32,
height: 32,
decoration: BoxDecoration(
border: Border.all(width: 2),
shape: BoxShape.circle
),
),
),
],
);
}
),
),
],
);
}
void _animationTick() {
final center = size.center(Offset.zero);
final anchor = ctrl.toScene(center);
ctrl.value = composeMatrixFromOffsets(
scale: ui.lerpDouble(1, 2, animationCtrl.value)!,
anchor: anchor,
translate: center,
);
}
}
https://stackoverflow.com/questions/74478910
复制相似问题