首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用InteractiveViewer变换在Matrix4中心放大

使用InteractiveViewer变换在Matrix4中心放大
EN

Stack Overflow用户
提问于 2022-11-17 16:26:09
回答 1查看 71关注 0票数 0

我有一个保存图像的InteractiveViewer小部件。

我如何使用InteractiveViewer缩放TransformationController,以便当用户点击按钮时,InteractiveViewer会放大到InteractiveViewer当前中心的任意缩放级别?

我试过用

代码语言:javascript
运行
复制
final currentScale = _transformationController.value.getMaxScaleOnAxis();
_transformationController.value = Matrix4.identity()..scale(currentScale * 1.1);

虽然这放大了预期,但它将当前位置重置到InteractiveViewer的左上角,这不是我想要的。

我的预期行为是,视图不会重置到左上角,而是在当前可见的视图中心放大。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-18 10:20:29

我设法解决了我的问题。对@pskink和我的同事大吼大叫。此实现将根据当前位置放大。

代码语言:javascript
运行
复制
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.maxWidthconstraints.maxHeight来自围绕InteractiveViewer小部件的LayoutBuilder

下面是@pskink在中心放大的实现:

代码语言:javascript
运行
复制
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,
    );
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74478910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档