带有覆盖小部件的可缩放图像

时间:2019-06-07 18:08:56

标签: flutter

我正在尝试制作一个自定义窗口小部件,以便用户可以缩放和平移图像并点击以在图像上覆盖点。我想我已经接近了,但是在水龙头下无法完全排成一列。

我从此处复制了相关的缩放范围: https://github.com/flutter/flutter/blob/master/examples/layers/widgets/gestures.dart

我也按照这篇文章将我的GestureDetector插入了自己的小部件中,以获得用于全局到本地偏移量转换的正确RenderBox。 flutter : Get Local position of Gesture Detector

BatchID Transprinted Date
------- ------------ ----
1       abc          2019-01-13
3       xyz          2019-06-06

但是我很难安排正确的布局。我认为我有两个问题:

  1. 图像喜欢跳到左上方。我不确定如何使它居中。
    enter image description here
  2. 放大时,我的_getFractionalOffset函数未返回正确的分数。屏幕截图中的图标未显示在我的点击下 enter image description here 我的矩阵数学很差,我对Flutter如何进行变换的理解也很差,因此我将不胜感激。

1 个答案:

答案 0 :(得分:0)

弄清楚了,我的代码遇到了几个问题,这些问题在复合时使调试变得烦人。

首先,我应该将比例尺/平移矩阵相乘,而不是相加:

vector.Matrix4 get _transformationMatrix {
  var scale = vector.Matrix4.diagonal3Values(_zoom, _zoom, 1.0);
  var translation = vector.Matrix4.translationValues(_offset.dx, _offset.dy, 0.0);
  var transform = translation * scale;
  return transform;
}

第二,我尝试着做从局部偏移到图像帧的转换,而不是让vector_math为我完成。新的叠加层偏移计算:

Offset _getOffset(BuildContext context, Offset globalPosition) {    
  var renderbox = context.findRenderObject() as RenderBox;
  var localOffset = renderbox.globalToLocal(globalPosition);    
  var localVector = vector.Vector3(localOffset.dx, localOffset.dy,0);
  var transformed =  Matrix4.inverted(_transformationMatrix).transform3(localVector);
  return Offset(transformed.x, transformed.y);
}

由于_transformationmatrix从图像帧到屏幕帧取一个点,因此我需要左乘逆数以从屏幕帧(localOffset)到图像帧(返回值)。

最后,我使用的是Positioned小部件,而不是Align,所以我可以以像素为单位设置位置:

double _width = 100;
double _height = 50;
List<Widget> _getOverlays(BuildContext context) {
  return widget.points
      .asMap() 
      .map((i, offset) => MapEntry(
          i,
          Positioned(
              left: offset.dx-_width/2,
              width:_width,
              top: offset.dy -_height/2,
              height:_height,
              child: _buildIcon((i + 1).toString(), context)
          )           
      ))
      .values
      .toList();
}

其中widget.points是上面List<Offset>返回的偏移量的_getOffset,而width / height是图标小部件的宽度和高度。 / p>

希望这对某人有帮助!