凸然

对flutter里的的MatrixUtils类中的方法的补充.

flutter中经常会有对widget、图片或文字等进行各种仿射变换(旋转、平移、缩放)的操作。


要做这么操作,必然会用到Matrix4对象,这个比android 的Matrix多了一维,但不用管它,仿射变换用不到这一维。


本身flutter就提供了MatrixUtils这个工具类,但这个工具类不够强大,有些安卓上系统自带的操作,它没有,所以只能自己去实现。

实现也不难,直接看下面的代码:

class MatrixUtilsEx {
  //matrix操作在translate之后, 相当于android中的postTranslate
  static Matrix4 postTranslate(Matrix4 matrix, double dx, double dy) {
    Matrix4 tmp = Matrix4.identity()..translate(dx, dy);
    return tmp.multiplied(matrix);
  }

//matrix操作在translate之前, 相当于android中的preTranslate
  static Matrix4 preTranslate(Matrix4 matrix, double dx, double dy) {
    Matrix4 tmp = Matrix4.identity();
    tmp[12] += dx;
    tmp[13] += dy;
    return matrix.multiplied(tmp);
  }

  //matrix操作在scale之后, 相当于android中的postScale
  static Matrix4 postScale(Matrix4 matrix, double scalex, double scaley) {
    Matrix4 tmp = Matrix4.identity();
    tmp[0] *= scalex;
    tmp[5] *= scaley;
    return tmp.multiplied(matrix);
  }

//matrix操作在scale之前, 相当于android中的preScale
  static Matrix4 preScale(Matrix4 matrix, double scalex, double scaley) {
    Matrix4 tmp = Matrix4.identity();
    tmp[0] *= scalex;
    tmp[5] *= scaley;
    return matrix.multiplied(tmp);
  }
  //在matrix操作之前先绕px,py点缩放,相当于android中的postScale(sx, sy, px, py)
  static Matrix4 postScalePivot(
      Matrix4 matrix, double scaleRatio, double px, double py) {
    Matrix4 tmp = Matrix4.identity();

    tmp = preTranslate(tmp, px, py);
    tmp = preScale(tmp, scaleRatio, scaleRatio);
    tmp = preTranslate(tmp, -px, -py);
    return tmp.multiplied(matrix);
  }
//在matrix操作之后绕px,py点缩放,相当于android中的preScale(sx, sy, px, py)
  static Matrix4 preScalePivot(
      Matrix4 matrix, double scaleRatio, double px, double py) {
    Matrix4 tmp = Matrix4.identity();

    tmp = preTranslate(tmp, px, py);
    tmp = preScale(tmp, scaleRatio, scaleRatio);
    tmp = preTranslate(tmp, -px, -py);
    return matrix.multiplied(tmp);
  }

  //matrix操作在rotate之后, 相当于android中的postRotate
  static Matrix4 postRotate(Matrix4 matrix, double rotateDegree) {
    Matrix4 tmp = Matrix4.identity();
    tmp.rotateZ(rotateDegree * pi / 180);
    return tmp.multiplied(matrix);
  }

  //matrix操作在rotate之前, 相当于android中的preRotate
  static Matrix4 preRotate(Matrix4 matrix, double rotateDegree) {
    Matrix4 tmp = Matrix4.identity();
    tmp.rotateZ(rotateDegree * pi / 180);
    return matrix.multiplied(tmp);
  }
//matrix操作之前先绕px,py点旋转, 相当于android中的postRotate(degrees, px, py)
  static Matrix4 postRotatePivot(
      Matrix4 matrix, double rotateDegree, double px, double py) {
    Matrix4 tmp = Matrix4.identity();
    tmp = preTranslate(tmp, px, py);
    tmp = preRotate(tmp, rotateDegree);
    tmp = preTranslate(tmp, -px, -py);
    return tmp.multiplied(matrix);
  }
//matrix操作之后,再绕px,py点旋转, 相当于android中的preRotate(degrees, px, py)
  static Matrix4 preRotatePivot(
      Matrix4 matrix, double rotateDegree, double px, double py) {
    Matrix4 tmp = Matrix4.identity();
    tmp = preTranslate(tmp, px, py);
    tmp = preRotate(tmp, rotateDegree);
    tmp = preTranslate(tmp, -px, -py);
    return matrix.multiplied(tmp);
  }

}

这样就能很方便的对widget,图片,文字等做些复杂的操作了,至于什么时候用 postxxx,什么时候用 prexxx
完全看你在实现复杂操作的时候,某一步用哪个实现的更方便。记住一点,不管 prexxx 还是 postxxx 都是对 canvas 坐标系的变换。牢记这一点,在实现复杂操作时,思路才能清晰。




版权声明:本文为凸然网站的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:对flutter里的的MatrixUtils类中的方法的补充.