对于前端来说,我感觉最大的魅力就是在于动画效果了;最初入坑前端就是想做出炫酷的动画,其实可以学习AE什么的,当时不懂,就入了前端程序员的坑。当然用代码实现出炫酷的动画效果,更会让自己充满成就感。
1. 动画简介
在一段时间内,快速地多次改变UI外观,由于人眼会产生视觉残留,所以最后会看到连续的动画。对于人眼来说,动画帧率超过16FPS,就比较流畅了,超过32FPS就会非常的细腻平滑,而超过32FPS,人眼基本上就感受不到差别了。由于动画的每一帧都是要改变UI输出,所以在一个时间段内连续的改变UI输出是比较耗资源的,对设备的软硬件系统要求都较高,所以在UI系统中,动画的平均帧率是重要的性能指标,而在Flutter中,理想情况下是可以实现60FPS的,这和原生应用能达到的帧率是基本是持平的。—— 《flutter实战.动画简介》
2. flutter动画
在web前端,我们实现动画可以通过css过渡元素,定义css关键帧,js等定义动画函数等方式去实现,那么flutter如何去实现动画效果呢?如果是想简单的实现动画,可以选择flutter内置的一些动画Widget,flutter已经封装好了:AnimatedPadding
,AnimatedPositioned
,AnimatedOpacity
,AnimatedAlign
,AnimatedContainer
,AnimatedDefaultTextStyle
,这些拿来即用,但是这些不能随心控制;想要自己自定义实现动画的话那就需要以下的几个步骤:
- 创建一个动画控制器
AnimationController
- 添加一个描述动画的过程
Curve
,返回的是一个Animation - 添加
tween
,控制动画的执行范围,需要执行animate方法,返回Animation
AnimationController
: 创建动画控制器,默认动画执行范围是[0,1],如果需要改变的话,需要用到tween
3. 开始制作简单的动画
动画效果:一个正方形,先变大,然后变颜色,然后再变小,还原颜色
前提准备,新建好项目,新建class AnimationDemo
class AnimationDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return AnimationDemoState();
}
}
class AnimationDemostate extends State<AnimationDemo> with SingleTickerProviderStateMixin {
// SingleTickerProviderStateMixin 性能有关,需要执行Ticker
// 动画控制器需要传这个参数,效果是在页面不可见的区域,动画不会执行,避免消耗资源。
}
3.1 定义动画和控制器变量
class AnimationDemostate extends State<AnimationDemo> with SingleTickerProviderStateMixin {
// SingleTickerProviderStateMixin 性能有关,需要执行Ticker
// 动画控制器需要传这个参数,效果是在页面不可见的区域,动画不会执行,避免消耗资源。
Animation animation;
AnimationController _animationController;
}
3.2 初始化动画变量
我们先尝试让红色的正方形在3秒内从10的宽高变道300的宽高,以下代码中做了以下几步
- 先创建了一个动画控制器,
duration
动画的持续时间,vsync
这个就是当前的State - 创建了一个动画函数
CurvedAnimation
它的是一个Animation
- 创建
Tween
,begin:10.0,end: 300.0,这个就是在3秒之内会生成10~300的值
new Tween
它是继承Animatable<T>
,而不是跟CurvedAnimation
一样继承Animation;那我们创建的Animatable
如何与Animation
形成映射呢?答案是执行animate方法把Animation
传进去,就形成了新的Animation
,我们就可以在Widget
中愉快使用了它了。 - 执行动画
_animationController.forward();
class AnimationDemostate extends State<AnimationDemo> with SingleTickerProviderStateMixin{
···
@override
void initState() {
// TODO: implement initState
_animationController = new AnimationController(
duration: Duration(seconds: 3),
vsync: this,
);
animation = new CurvedAnimation(
parent: _animationController,
curve: Curves.ease
);
// Tween begin,end 就是大小变化的区间
animationSize = new Tween(begin: 10.0, end: 300.0).animate(animation)
..addListener((){
setState(() {
});
});
_animationController.forward();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
···
new Container(
width: animationSize.value,
height: animationSize.value,
decoration: BoxDecoration(
color: Colors.red,
),
)
···
)
}
···
}
经过上面步骤之后我们来看下效果:
皆大欢喜,我们已经成功了第一步!能有动画的效果了,我们继续深入后续的步骤
3.3 让红色正方形变大的过程中变成其他颜色
这种相当于是关键帧的意思,就是先变大,在变大的过程中某个时间开始变颜色;在web中我们知道css中有@keyframe
可是设置关键帧,来进行交织动画,flutter中我们如何实现呢?
在3.2步骤中我们创建过一个动画曲线CurvedAnimation
,curve
传的是flutter内置的动画函数Curves.ease
,在vscode中打出Curves后编辑器会有提示所有的内置的函数;我们要打关键帧的话,关键在于此curve
,这里需要用到Interval(start, end)
,这个Interval通过start和end我们就能知道了,它表示的是一段时间间隔,可以传入curve
参数。
了解上面的内容之后,我们思路应该清爽了,那继续深入
3.3.1 使正方形变大的过程中由红色变成蓝色
class xxx extends xxx with xxx {
// 定义变量
Animation animationColor;
// 初始化变量
void initState() {
// TODO: implement initState
_animationController = new AnimationController(
duration: Duration(seconds: 3),
vsync: this,
);
animation = new CurvedAnimation(
parent: _animationController,
curve: new Interval(0, 0.5) // 这里执行间隔 是3秒中0~50%的时间执行正方形变大,默认动画
);
animationSize = new Tween(begin: 10.0, end: 300.0).animate(animation)
..addListener((){
setState(() {
});
});
animation = new CurvedAnimation(
parent: _animationController,
curve: new Interval(0.5, 1.0, curve: Curves.easeIn) // 50%~100%执行变颜色,并且动画是easeIn
);
animationColor = new ColorTween(begin: Colors.white, end: Colors.blue).animate(animation)
..addListener((){
setState(() {
});
});
}
}
通过上面步骤之后
我们来看看最终的的效果:
最后想实现循环往复的效果
需要在动画监听状态中去改变动画的方向就可以了
方法如下:
animation.addStatusListener((status){
if (status == AnimationStatus.completed) {
_animationController.reverse();
} else if (status == AnimationStatus.dismissed) {
_animationController.forward();
}
});
来看看效果:
总结
这边主要是对flutter动画的一个简单的入门,按照上面步骤一步步的去实现flutter的动画,应该就会对flutter动画有了一定的了解了,具体深入的了解可以看官方文档和其他资料的书籍,如果文中有讲述不到位的地方,或者有错误的地方,也请大佬们多多指教,康桑密达!