
微信交流群
# Curve
动画中还有一个重要的概念就是 Curve,即动画执行曲线。Curve 的作用和 Android 中的 Interpolator(差值器)是一样的,负责控制动画变化的速率,通俗地讲就是使动画的效果能够以匀速、加速、减速、抛物线等各种速率变化。
蓝色盒子大小 100 变大到 200,动画曲线设置为 bounceIn(弹簧效果) :
class CurveDemo extends StatefulWidget {
_CurveDemoState createState() => _CurveDemoState();
}
class _CurveDemoState extends State<CurveDemo>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation _animation;
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 1000))
..addListener(() {
setState(() {});
});
_animation = Tween(begin: 100.0, end: 200.0)
.chain(CurveTween(curve: Curves.bounceIn))
.animate(_controller);
}
Widget build(BuildContext context) {
return Center(
child: GestureDetector(
onTap: () {
_controller.forward();
},
child: Container(
height: _animation.value,
width: _animation.value,
color: Colors.blue,
alignment: Alignment.center,
child: Text(
'点我变大',
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
),
);
}
void dispose() {
super.dispose();
_controller.dispose();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
动画加上Curve 后,AnimationController 的最小/大值必须是 [0,1]之间,例如下面的写法就是错误的:
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 1000),lowerBound: 100.0,upperBound: 200.0)
..addListener(() {
setState(() {});
});
_animation = CurveTween(curve: Curves.bounceIn).animate(_controller);
1
2
3
4
5
6
2
3
4
5
6
抛出如下异常:
正确写法:
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 1000))
..addListener(() {
setState(() {});
});
_animation = Tween(begin: 100.0, end: 200.0)
.chain(CurveTween(curve: Curves.bounceIn))
.animate(_controller);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
系统已经提供了38种常用到动画曲线:
linear
decelerate
bounceIn
bounceOut
elasticIn
其余动画效果可以官方文档查看。
通常情况下,这些曲线能够满足 99.99% 的需求,很多时候设计也就是告诉你动画 先快后慢 或者 先慢后快,所以选个类似的就可以了,但有一些 特别 的设计非要一个系统没有的动画曲线,要怎么办?
# 那就自定义一个动画曲线
其实自定义一个动画曲线难点在 数学 上,怎么把数学公式用代码实现才是难点。
下面是一个 楼梯效果 的动画曲线:
自定义动画曲线需要继承 Curve 重写 transformInternal 方法即可:
class _StairsCurve extends Curve {
double transformInternal(double t) {
return t;
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
直接返回 t 其实就是线性动画,即 Curves.linear,实现楼梯效果动画代码如下:
class _StairsCurve extends Curve {
//阶梯的数量
final int num;
double _perStairY;
double _perStairX;
_StairsCurve(this.num) {
_perStairY = 1.0 / (num - 1);
_perStairX = 1.0 / num;
}
double transformInternal(double t) {
return _perStairY * (t / _perStairX).floor();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
修改开始处的案例,使用此曲线:
_animation = Tween(begin: 100.0, end: 200.0)
.chain(CurveTween(curve: _StairsCurve(5)))
.animate(_controller);
1
2
3
2
3
版权所有,禁止私自转发、克隆网站。