Флаттер: как установить максимальный / минимальный масштаб с помощью matrix_gesture_detector - PullRequest
1 голос
/ 26 марта 2020

Я пытаюсь сделать масштаб колонны / подвижным. Но как я могу установить максимальное увеличение и минимальное увеличение? Так что вы не приближаетесь к бесконечности.

Используя этот метод прямо сейчас:

 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(
      ),
    ),

1 Ответ

0 голосов
/ 21 апреля 2020

У меня возникла та же проблема, и я потратил некоторое время, но нашел решение.

После того, как немного покопался в Transform.scale источнике Флаттера, эта строка дает нам подсказку :

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

Используются диагональные значения из Matrix4, которые вы получаете в onMatrixUpdate. Таким образом, требуется x от 1-го вектора4, y от 2-го и z от 3-го. (4-е исправлено из того, что я могу сказать). Так что это те значения, которые вам нужно ограничить. В этом примере я создал небольшой _minMax метод, который ограничивает масштаб до релевантного минимума / максимума, когда это уместно (их можно пропустить null, чтобы игнорировать любую из сторон предела).

Я использовал это для ограничения масштаба:

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;
    });
  },
...