Transform
Transform
组件可以对子组件进行变化,比如旋转、平移、缩放等。
- 构造函数
const Transform({
super.key,
required this.transform,//Matrix4对象
this.origin,//是一个Offset对象
this.alignment,//是origin的对其方式,是一个AlignmentGeometry对象
this.transformHitTests = true,//点击区域是否也做相应的变换,为true时执行相应的变换,为false不执行
this.filterQuality,//图像的取样质量
super.child,
})
- 基本用法:
Transform(
transform: Matrix4.rotationZ(0.5),//绕z轴旋转弧度
//origin参数表示变换矩阵的坐标,默认是(0,0)即左上角,如果想围绕圆心旋转
origin: const Offset(50,50),
child: Container(
width: 100,
height: 100,
color: Colors.green,
),
)
Transform
为方便调用构建了Transform.translate
、Transform.rotate
和Transform.scale
。
Transform.translate
构造函数
Transform.translate({
super.key,
required Offset offset,
this.transformHitTests = true,
this.filterQuality,
super.child,
})
用法:
Transform.translate(
offset: const Offset(50.0,100.0),
child: Container(
width: 100,
height: 100,
color: Colors.blue,
)
),
Transform.rotate
构造函数:
Transform.rotate({
super.key,
required double angle,
this.origin,
this.alignment = Alignment.center,
this.transformHitTests = true,
this.filterQuality,
super.child,
})
用法:
Transform.rotate(
angle: pi/4,//pi/4,也就是45度
child: Container(
width: 100,
height: 100,
color: Colors.amber,
),
)
Transform.scale
构造函数:
Transform.scale({
super.key,
double? scale,//整体缩放
double? scaleX,//宽度缩放
double? scaleY,//高度缩放
this.origin,
this.alignment = Alignment.center,
this.transformHitTests = true,
this.filterQuality,
super.child,
})
用法:
Transform.scale(
//scale: 1.5,
scaleX: 1.5,
scaleY: 1,
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
)
效果:
Vector3
Vector
是向量,矢量的意思,向量既有大小,又有方向,Verctor3
就是三维向量,一个三维向量会有三个分量,分别是 x,y,z。
Verctor3
类在flutter中有两种构造方法,三个参数分别对应x/y/z轴方向缩放。
factory Vector3(double x, double y, double z) =>
new Vector3.zero()..setValues(x, y, z);
factory Vector3.array(List<double> array, [int offset = 0]) =>
new Vector3.zero()..copyFromArray(array, offset);
使用Vector3
,我们需要引入vector_math_64包,这个是flutter自带的,不需要我们去安装
import 'package:vector_math/vector_math_64.dart' as vector;
注意:vector_math和vector_math_64应该是针对32bit和64bit变体的,它们在包中作为两个不同的库实现。因此,需要在使用这些库的方式上保持一致性。
export 'package:vector_math/vector_math_64.dart'
或者
export 'package:vector_math/vector_math.dart'
Matrix4
矩阵变换
Matrix4
是一个4D矩阵,通过它我们可以实现各种矩阵操作。
- 构造
Matrix4(double arg0, … double arg15)
Matrix4
默认构造函数由 16 个参数,从左到右从上到下依此排列为一个四阶矩阵;
Matrix4(
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
)
Matrix4.identity()
(初始化)
Matrix4.identity()
会初始化一个如上的 Matrix4
,可在此基础上进行其他矩阵操作;
Transform(
transform: Matrix4.identity()..rotateZ(pi/16),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.identity'),),
),
)
- Matrix4.zero()
(置零矩阵)
Matrix4.zero()
会初始化一个所有参数值为 0 的空矩阵,在此基础上设置具体的变化矩阵:
Transform(
transform: Matrix4.zero()..setIdentity()..rotateZ(pi/16),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.zero'),),
),
),
Matrix4.fromList()
将一个16位的一维数组转换成4*4的矩阵,
Matrix4.fromList()
将 List 列表中数据赋值进入 ,Matrix4(double arg0, … double arg15)
:
List<double> list = [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
];
....
Transform(
transform: Matrix4.fromList(list)..rotateZ(pi/16),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.fromList'),),
),
),
Matrix4.copy()
(复制)
Matrix4.copy()
拷贝一个已有的 Matrix4
:
Transform(
//copy:复制一个4*4的矩阵
// transform: Matrix4.copy(Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)),
transform: Matrix4.copy(Matrix4.identity()),//同上都是复制一个4*4的矩阵
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.copy'),),
),
),
Matrix4.columns()
设置一个新的矩阵,Matrix4.columns()
由四个 4D 列向量组成。
transform: Matrix4.columns(
vector.Vector4(1.0,0.0,0.0,0.0),
vector.Vector4(0.0,1.0,0.0,0.0),
vector.Vector4(0.0,0.0,1.0,0.0),
vector.Vector4(0.0,0.0,0.0,1.0),
),
Matirx4.inverted()
Matrix4.inverted()
为逆向矩阵,与原 Matrix4
矩阵相反(矩阵坐标沿着左对角线对称)
Transform(
transform: Matrix4.inverted(Matrix4.fromList(list)..rotateZ(pi/16)),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.inverted'),),
),
),
Matrix4.outer()
(合并)
Matrix4.outer()
为两个四阶矩阵的合并乘积,注意两个四阶矩阵的先后顺序决定最终合并后的矩阵数组:
transform: Matrix4.outer(v.Vector4(1.0, 1.0, 1.0, 1.20), v.Vector4.identity()),
transform: Matrix4.outer(v.Vector4.identity(), v.Vector4(1.0, 1.0, 1.0, 1.20)),
Matrix4.diagonal3()
(缩放)
Matrix4.diagonal3()
通过 Vector3
设置缩放矩阵:
Transform(
transform: Matrix4.diagonal3(vector.Vector3(1.5,1.0,1.0)),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.diagonal3'),),
),
),
const SizedBox(height: 10,),
Transform(
transform: Matrix4.diagonal3(vector.Vector3.array([0.5,0.5,0.5])),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.diagonal3'),),
),
),
Matirx4.diagonal3Values()
(缩放)
Matrix4.diagonal3Values()
类似于将上述构造方法提取出来,直接对三个参数进行缩放赋值:
Transform(
transform: Matrix4.diagonal3Values(1.5,1.0,1.0),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.diagonal3Values'),),
),
),
const SizedBox(height: 10,),
Transform(
transform: Matrix4.diagonal3Values(0.5,0.5,0.5),
origin: const Offset(100,50),//旋转点
child: Container(
width: 200,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.diagonal3Values'),),
),
),
Matrix4.translation()
(平移)
Matrix4.translation
同样通过 Vector3
构造方法的各参数设置矩阵平移量;水平向右为 x 轴正向,竖直向下为 y 轴正向:
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform(
transform: Matrix4.translation(vector.Vector3(10.0,10.0,10.0)),
child: Container(
width: 150,
height: 50,
color: Colors.green,
child: const Center(child: Text('Matrix4.translation'),),
),
),
Transform(
transform: Matrix4.translation(vector.Vector3.array([-10.0,-10.0,-10.0])),
child: Container(
width: 150,
height: 50,
color: Colors.green,
child: const Center(child: Text('Matrix4.translation'),),
),
),
],
)
Matrix4.translationValues()
(平移)
Matrix4.translationValues()
将矩阵平移量直接赋值展示,效果同上Matrix4.translation()
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform(
transform: Matrix4.translationValues(10.0,10.0,10.0),
child: Container(
width: 150,
height: 50,
color: Colors.green,
child: const Center(child: Text('Matrix4.translation'),),
),
),
Transform(
transform: Matrix4.translationValues(-10.0,-10.0,-10.0),
child: Container(
width: 150,
height: 50,
color: Colors.green,
child: const Center(child: Text('Matrix4.translation'),),
),
),
],
)
Matrix4.rotationX()
(沿 x 轴方向旋转)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform(
transform: Matrix4.rotationX(pi/3),
origin: const Offset(100,100),//旋转点
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.rotationX'),),
),
),
Transform(
transform: Matrix4.rotationX(pi/6),
origin: const Offset(100,100),//旋转点
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.rotationX'),),
),
),
],
)
Matrix4.rotationY()
(沿 y 轴方向旋转)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform(
transform: Matrix4.rotationY(pi/3),
origin: const Offset(100,100),//旋转点
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.rotationY'),),
),
),
Transform(
transform: Matrix4.rotationY(pi/6),
origin: const Offset(100,100),//旋转点
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.rotationY'),),
),
),
],
)
Matrix4.rotationZ()
(沿 z 轴方向旋转)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Transform(
transform: Matrix4.rotationZ(0),
origin: const Offset(50,50),//旋转点
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.rotationZ'),),
),
),
Transform(
transform: Matrix4.rotationZ(45),
origin: const Offset(50,50),//旋转点
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('Matrix4.rotationZ'),),
),
),
],
)
Matrix4.skewX()
(skewX() 是沿 x 轴方向斜切)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform(
transform: Matrix4.skewX(0),
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('skewX'),),
),
),
Transform(
transform: Matrix4.skewX(pi/6),
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('skewX'),),
),
),
],
),
Matrix4.skewY()
(沿 y 轴方向斜切)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Transform(
transform: Matrix4.skewY(0),
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('skewY'),),
),
),
Transform(
transform: Matrix4.skewY(pi/6),
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('skewY'),),
),
),
],
),
Matrix4.skew()
(沿 x / y 轴方向斜切)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Transform(
transform: Matrix4.skew(0,0),
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('skew'),),
),
),
const SizedBox(width: 50,),
Transform(
transform: Matrix4.skew(pi/6,pi/6),
child: Container(
width: 100,
height: 100,
color: Colors.green,
child: const Center(child: Text('skew'),),
),
),
],
),
Matrix4.compose()
Matrix4.compose()
可以将平移/旋转/缩放共同组合操作。
- 构造函数
Matrix4.compose(
Vector3 translation, //平移
Quaternion rotation, //旋转
Vector3 scale //缩放
)
例子:
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
class Matrix4Page extends StatefulWidget {
const Matrix4Page({Key? key}) : super(key: key);
@override
State<Matrix4Page> createState() => _Matrix4PageState();
}
class _Matrix4PageState extends State<Matrix4Page> with TickerProviderStateMixin {
final Matrix4 _begin = Matrix4.compose(
vector.Vector3(0,0,1),
vector.Quaternion.euler(0, 0, 0),
vector.Vector3(1,1,1)
);
final Matrix4 _midway = Matrix4.compose(
vector.Vector3(0,0,1),
vector.Quaternion.euler(1, -0.2, 0),
vector.Vector3(.8,.8,.8)
);
final Matrix4 _finally = Matrix4.compose(
vector.Vector3(0,0,1),
vector.Quaternion.euler(1, 0, 0),
vector.Vector3(1,1,1)
);
Matrix4 _end = Matrix4.compose(
vector.Vector3(0,0,1),
vector.Quaternion.euler(1, -0.2, 0),
vector.Vector3(0.8,0.8,0.8)
);
@override
Widget build(BuildContext context){
return TweenAnimationBuilder(
tween: Tween(begin: _begin,end: _end),
duration: const Duration(seconds: 2),
builder: (BuildContext context,Matrix4 value,Widget? _){
return Transform(
transform: value,
child: Scaffold(
appBar: AppBar(
title: const Text('Matrix4'),
backgroundColor: Colors.transparent,
),
body: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
setState(() {
if(_end == _begin){
_end = _midway;
}else if(_end == _midway){
_end = _finally;
}else{
_end = _begin;
}
});
},
child: const Icon(Icons.rotate_left),
),
),
);
}
);
}
}