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类中的方法的补充.