1.Transform介紹
可以在其子組件繪制前對其應用一些矩陣變換來實現(xiàn)一些特效渗钉。
這里需要注意的是這種變換特效是應用在繪制階段而不是布局階段彤恶,也就是說子控件雖然進行了變換钞钙,但是他所占用的實際空間,位置等都是固定不變的声离,只是視覺上改變了芒炼。
2.Transform.rotate
- angle:旋轉弧度 注意這里不是角度,需要將角度轉為弧度术徊,180度 = π弧度 即1度=π/180 弧度
- origin:以某一個原點旋轉本刽,這個是相對于alignment位置所設置的Offset的偏移點為原點旋轉
- alignment = Alignment.center:以alignment位置為原點旋轉
- child:
關于Alignment之前已經(jīng)介紹過了:Flutter(44):Layout組件之Container
這里的旋轉內部實現(xiàn)是Matrix4.rotationZ(angle)變換,即以Z軸為旋轉軸旋轉angle弧度
我們來看個例子:
_myChild() {
return Text(
'Hello Flutter',
style: TextStyle(
backgroundColor: Colors.blue,
fontSize: 20,
color: Colors.white,
),
);
}
_myTransformRotate() {
return Stack(
children: [
Center(
child: _myChild(),
),
Center(
child: Transform.rotate(
angle: dartMath.pi * 0.25,
alignment: Alignment.center,
child: _myChild(),
),
),
Center(
child: Transform.rotate(
angle: dartMath.pi * 0.25,
origin: Offset(50, 50),
alignment: Alignment.center,
child: _myChild(),
),
),
Center(
child: Transform.rotate(
angle: dartMath.pi * 0.25,
alignment: null,
child: _myChild(),
),
),
],
);
}
這里我們分別有四個“Hello Flutter”赠涮,第一個不做任何變換子寓;第二個設置Alignment.center為原點旋轉45度,即以控件的中心點旋轉45度笋除;第三個是以Alignment.center偏移Offset(50, 50)的點為原點旋轉15度斜友,即以控件的中心點,向右偏移50垃它,向下偏移50的一個點為原點旋轉45度鲜屏;第四個就是設置alignment旋轉45度,即以控件的Alignment.topLeft(左上角)為原點旋轉45度国拇。
- Stack組件洛史,它是一個多子節(jié)點組件,支持疊放子控件酱吝,這個組件后面我們會詳細介紹也殖。
- dartMath其實是導入的dart中的math
import 'dart:math' as dartMath;
3.Transform.translate
- offset:Offset 偏移位置
- child:
這里就是平移變換到原位置的Offset位置,內部實現(xiàn)是Matrix4.translationValues(offset.dx, offset.dy, 0.0)變換
_myTransformTranslate() {
return Stack(
children: [
Center(
child: Transform.translate(
offset: Offset(0, 0),
child: _myChild(),
),
),
Center(
child: Transform.translate(
offset: Offset(50, 50),
child: _myChild(),
),
),
],
);
}
這里就是將“Hello Flutter”相對于原來位置向右平移50向下平移50
4.Transform.scale
- scale:縮放系數(shù)
- origin:以某一個原點縮放掉瞳,這個是相對于alignment位置所設置的Offset的偏移點為原點縮放
- alignment = Alignment.center:以alignment位置為原點縮放
- child:
這里的縮放內部實現(xiàn)是Matrix4.diagonal3Values(scale, scale, 1.0)變換
_myTransformScale() {
return Stack(
children: [
Center(
child: Transform.scale(
scale: 2,
origin: Offset(50, 50),
alignment: Alignment.center,
child: _myChild(),
),
),
Center(
child: Transform.scale(
scale: 2,
alignment: Alignment.center,
child: _myChild(),
),
),
Center(
child: Transform.scale(
scale: 1,
alignment: Alignment.center,
child: _myChild(),
),
),
],
);
}
這里呢我們從下往上看毕源,最后一個就是以Alignment.center為原點縮放一倍,即維持原樣陕习;倒數(shù)第二個就是以Alignment.center為原點放大兩倍霎褐;倒數(shù)第三個也就是第一個是以Alignment.center向左偏移50,向下偏移50的位置為原點放大兩倍
5.Transform
- transform:Matrix4
- origin:相對于alignment的偏移原點
- alignment:alignment
- child:
前面幾種的變化其實都是基于Matrix4進行的變換该镣,那么如果以上三種無法滿足需求還有一種就是由你自己去設置transform變換
例如我們這里想實現(xiàn)一個以中心點為原點冻璃,X軸為旋轉軸旋轉180的變換
_myTransform(Matrix4 transform) {
return Center(
child: Transform(
transform: transform,
alignment: Alignment.center,
child: _myChild(),
),
);
}
body: _myTransform(Matrix4.rotationX(dartMath.pi * 0.75)),
6.Matrix4
Matrix4還提供了非常之多的矩陣變換,例如沿Y軸旋轉损合,沿X扭曲省艳,沿Y軸扭曲,還支持復合嫁审。我們這里簡單介紹一些:
平移
- Matrix4.translationValues(double x, double y, double z)
x代表X軸跋炕,大于0向右,小于0向左律适;y代表Y軸辐烂,大于0向下遏插,小于0向上;z代表Z軸纠修,大于0凸起胳嘲,小于0下凹,但是這個在這種平面圖上是顯示不出來效果的扣草。 - Matrix4.translation(Vector3 translation)
這種方式是使用向量的方式了牛,需要import 'package:vector_math/vector_math_64.dart',
Vector3(double x, double y, double z)辰妙,跟第一種本質沒區(qū)別鹰祸。
body: _myTransform(Matrix4.translationValues(-50, 20, 0)),
body: _myTransform(Matrix4.translation(vectorMath.Vector3(-50, 20, 0))),
body: _myTransform(
Matrix4.translation(vectorMath.Vector3.array([-50, 20, 0]))),
旋轉
- Matrix4.rotationX(double radians)
X軸旋轉,旋轉弧度大于0就是由Y軸正方向向Z軸正方向旋轉密浑,小于0就是Z軸正方向向Y軸正方向旋轉
body: _myTransform(Matrix4.rotationX(dartMath.pi * 0.25)),
- Matrix4.rotationY(double radians)
沿Y軸旋轉福荸,旋轉弧度大于0就是由X軸正方向向Z軸正方向旋轉,小于0就是Z軸正方向向X軸正方向旋轉
body: _myTransform(Matrix4.rotationY(dartMath.pi * 0.25)),
- Matrix4.rotationZ(double radians)
沿Z軸旋轉肴掷,旋轉弧度大于0就是由Y軸正方向向X軸正方向旋轉,小于0就是X軸正方向向Y軸正方向旋轉
body: _myTransform(Matrix4.rotationZ(dartMath.pi * 0.25)),
縮放
- Matrix4.diagonal3(Vector3(double x, double y, double z))
- Matrix4.diagonal3Values(double x, double y, double z)
這里的值表示縮放的比例背传,分別沿x,y,z三個方向呆瞻,x軸正向向右,y軸正向向下径玖,z軸正向從屏幕朝上痴脾,正值表示正向,>1表示放大梳星,小于1大于0表示縮小赞赖,負值表示反向,會翻轉冤灾。
body: _myTransform(Matrix4.diagonal3(vectorMath.Vector3(2, -0.8, 0))),
扭曲
- Matrix4.skewX(double alpha)
沿X軸扭曲
body: _myTransform(Matrix4.skewX(dartMath.pi * 0.25)),
- Matrix4.skewY(double beta)
沿Y軸扭曲
body: _myTransform(Matrix4.skewY(dartMath.pi * 0.25)),
- Matrix4.skew(double alpha, double beta)
body: _myTransform(Matrix4.skew(dartMath.pi * 0.2,dartMath.pi * 0.1)),
其他還有使用矩陣創(chuàng)建前域,取反(inverted),合并(outer)韵吨,復合(compose)這些都些矩陣變換都需要對線性代數(shù)有了解了匿垄,這里就不說了。
7.驗證Transform變換是在繪制階段而不是在布局階段
_myRow() {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Transform.scale(
scale: 2,
alignment: Alignment.center,
child: _myChild(),
),
_myChild()
],
),
);
}
這里可以看到前一個“Hello Flutter”放大后并沒有影響后面一個的位置归粉,由此也可以看出變換是繪制階段而不是在布局階段椿疗。這種矩陣變換的優(yōu)點就是發(fā)生在繪制階段,他不需要去重新布局或者構建糠悼,對性能上很友好届榄。
下一節(jié):Layout組件之UnconstrainedBox