- 背景颜色层。从上到下的渐变效果
- 云层。只有一种图片,对其位移、数量、染色做不同变化达到不同效果
- 雨雪层。为雨雪天气单独做了动画,很炫酷。
好,真正的主角就是这个雨雪层,为了更好的预览效果,在关于页面有上角添加切换天气类型的入口,实时查看不同气象下不同的背景效果。如下图,为雨雪的最终效果(gif 效果看起来会失真,请下载 apk 自行体验):
不得不说,如此复杂的动画(复杂并不是指多难实现,而是不停的绘制很多图片下),Flutter 还能有不错的性能表现,媲美原生效果。
效果实现
这里不赘述绘制和动画相关知识,网上已经有很多文章介绍,本篇只针对项目中用到的实现方式和相关知识进行讲述,具有一定的局限性,适合简单的绘制动画逻辑。
创建绘制类
因为 Flutter 处处是 widget,自定义 View 需要用到的是 CustomPaint,而成员变量中需要传入实现 CustomPainter 的类,那咱们先创建此类。
class RainSnowPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
复制代码
有没有很熟悉,看到了 Canvas 的类,自然也有 Paint 类,有了画笔和画板,剩下就好办了。
构造雨雪对象
对需要实现的效果进行分析,首先雨雪效果是由一张图片不同属性拼接而成,每个雨滴和雪花落实在屏幕上,必须有 x,y 的坐标属性。为了营造远近的效果,需要加上 scale 值,由于更加还原真实的视觉效果,雨滴的远近,必然速度上和清晰度上会有差异,因此加上 speed 和 alpha 属性,再加上其他计算用的属性,最后类的声明如下:
class RainSnowParams {
double x;
double y;
double speed;
double scale;
double width;
double height;
double alpha;
WeatherType weatherType;
RainSnowParams(this.width, this.height, this.weatherType);
}
复制代码
属性初始化
有了属性后,接下来就是对属性进行赋值,为了保证效果更加的还原,所有属性既要有规则,又要随机。怎么解释规则性和随机性都要同时拥有,就拿雨速而言,小雨相对于大雨,雨的速度稍慢,但是不能很慢,并且每滴雨滴的速度不一样,这就致使小雨的速度必然在一个区间下随机,