Flutter:如何使用matrix_gesture_detector设置最大/最小刻度 [英] Flutter: How to set a max/min scale using matrix_gesture_detector

查看:338
本文介绍了Flutter:如何使用matrix_gesture_detector设置最大/最小刻度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使列缩放/可移动。但是,如何设置最大变焦和最小变焦呢?这样就不会放大到无限远。

Im trying to make a Column scale/movable. But how can I set a max zoom and a min zoom? So that you don´t zoom to infinity.

现在使用此方法:

 Matrix4 matrix = Matrix4.identity();

     MatrixGestureDetector(
      shouldRotate: false
      onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
        setState(() {
          matrix = m;
        });
      },
      child: Transform(
        transform: matrix,
        child: Column(
      ),
    ),


推荐答案

我遇到了同样的问题,

I had the same problem and took a while but came across the solution.

在Flutter的 Transform.scale 揭示了这一行,给我们一个提示:

After digging around just a bit in Flutter's Transform.scale source reveals this line which gives us a hint:

transform = Matrix4.diagonal3Values(scale, scale, 1.0)

它使用从 onMatrixUpdate中收到的 Matrix4 的对角线值。因此,需要 x 从第一个Vector4开始, y 从第二个开始, z 从第三个开始。 (据我所知,第四项是固定的)。因此,这些是您需要限制的值。在此示例中,我制作了一个小的 _minMax 方法,该方法在相关时将比例尺限制在相关的最小/最大值(可以将其传递为 null 忽略限制的任一边。)

It's using the diagonal values from the Matrix4 you receive in onMatrixUpdate. So it takes x from the 1st Vector4, y from the 2nd, and z from the 3rd. (the 4th is fixed from what I can tell). So those are the values you need to limit. In this example I've made a small _minMax method which bounds the scale to the relevant min/max when relevant (they can be passed null to ignore either side of the limit).

我用它来限制规模:

typedef MathF<T extends num> = T Function(T, T);
typedef VFn = Vector4 Function(double x, double y, double z, double w);

double _minMax(num _min, num _max, num actual) {
  if (_min == null && _max == null) {
    return actual.toDouble();
  }

  if (_min == null) {
    return min(_max.toDouble(), actual.toDouble());
  }

  if (_max == null) {
    return max(_min.toDouble(), actual.toDouble());
  }

  return min(_max.toDouble(), max(_min.toDouble(), actual.toDouble()));
}

// ... ... ...

onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
    var finalM = Matrix4.copy(m);
    Map<int, VFn> colmap = {
      0: (x, y, z, w) {
        x = _minMax(widget.minScale, widget.maxScale, x);
        return Vector4(x, y, z, w);
      },
      1: (x, y, z, w) {
        y = _minMax(widget.minScale, widget.maxScale, y);
        return Vector4(x, y, z, w);
      },
      2: (x, y, z, w) {
        z = _minMax(widget.minScale, widget.maxScale, z);
        return Vector4(x, y, z, w);
      },
    };
    for (var col in colmap.keys) {
      var oldCol = m.getColumn(col);
      var colD = colmap[col];
      if (colD != null) {
        finalM.setColumn(col, colD(oldCol.x, oldCol.y, oldCol.z, oldCol.w));
      }
    }
    setState(() {
      matrix = finalM;
    });
  },

这篇关于Flutter:如何使用matrix_gesture_detector设置最大/最小刻度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆