Compose Desktop展现一场雨过天晴

最近这天气就跟产品的需求一样变化无常,经常早上进地铁站之前就下一场大雨,然后等出了地铁站以后,雨就停了,甚至有时候会直接出太阳,不愧是魔都的天气,有个性,有想法,那么这次我就打算用Compose Desktop来实现一个这样的雨过天晴的过程

下大雨

下雨的过程其实就是若干条直线从窗口的顶部掉落至底部的过程,再细分一下就是绘制一根直线,然后不停改变它y坐标的值,那么我们就先从画一根直线开始

image.png

raining函数就代表着一个下雨的场景,在里面调用了函数drawLine在窗口中央位置画了一根竖线,这个竖线就作为雨滴的模型,现在这个雨滴还不会动的,如果要让它动起来必须改变startend的y坐标,那么就要使用循环动画来改变这个y坐标的值

0608aa1.gif

由于雨滴坠落的过程是个加速度运动,所以这里使用了FastOutLinearInEasing曲线变化,然后在刚才的直线的startend的y坐标上加上dropY1的值,就实现了这个雨滴坠落的过程,现在一个雨滴的坠落完成了,那么多个雨滴的坠落如何实现呢,我们先要把宽度分成若干份,每一份就是一个雨滴坠落的轨道

image.png

这个xList里面就维护着所有轨道的x坐标,然后我们直接遍历这个list,把刚刚雨滴的代码放在里面,多个雨滴的坠落就出来了

0608aa2.gif

看着怪怪的是不,这雨滴有点太整齐了,现实中的雨滴是错落分布的,并且垂直方向上的雨滴数量也不可能是一个,那么要实现垂直方向上多个雨滴的话,我们肯定要在一个轨道上多画几个雨滴,并且再创建几个与dropY1一样的变量,但是动画时间不同,每一个雨滴用一种动画变量,通过这种坠落速度不同的方式来达到垂直方向上显示多个雨滴的视觉效果

image.png

dropY1~dropY6都是动画时间不同的循环动画,我们在刚才的list遍历中针对每一个循环动画来画一个雨滴,另外为了达到有点错落感的效果,在偶数轨道上使用dropY1,dropY3,dropY5,在单数轨道上用另外三个,我们看下代码与实际效果

image.png0608aa3.gif

有没有一点像下雨的样子了呢?我们接着给天上画点乌云

乌云

乌云这种不规则的图形怎么画呢?其实也容易,可以把乌云看成是一个个椭圆连在一起,相连部分重叠起来就好了,首先我们先创建绘制椭圆需要用的Path

image.png

这个cloudPaths里面就维护着绘制椭圆需要用到的Path,这里首先把宽度分成十份,每一份就作为椭圆的中心点的x坐标,y坐标就固定为一个值,然后就可以遍历这个数组来绘制这些椭圆

image.png0608aa4.gif

下雨的部分我们完成了,接下去就是晴天的绘制

蓝天绿地

晴天的绘制我们放在另一个Composable函数里面,命名为sunny

image.png

其中绘制蓝天绿地其实就是画两条宽度占满窗口的直线,两者的高度比例为三比一

image.png

这边我们给两条直线出现的时候加上一点透明渐变的动画,所以需要用到animateFloatAsState函数

image.png

这里新增grassStateskyState两个变量,作为动画切换的开关,然后我们把grassAlphaskyAlpha两个变量赋值给drawLine函数的alpha属性

image.png

两个开关开启的时机,我们就设定成页面出来时候的200毫秒以后,这里使用Flow来设置这个延时的时间

image.png

来看下实际效果

0609aa1.gif

太阳

大晴天肯定得要有太阳,太阳其实就是一个圆,我们用drawCircle函数就可以实现,那么画圆的话首先就要确定好圆的中心点坐标以及半径

image.png

有了这三个,我们就可以把太阳的这个圆画出来了,但是这里也想让太阳出来的时候跟蓝天绿地一样有一个透明渐变的过程,在蓝天绿地的动画结束后,开始太阳的动画,所以太阳也需要一个开关以及一个由开关控制的动画

image.png

然后就可以把sunAlpha这个变量跟我们上面创建的圆心坐标与半径的另外三个变量都代入到drawCircle函数里面

image.png

我们再把开启sunState的时机放在绿地动画结束以后的回调函数里面,这样就把太阳跟蓝天绿地的动画连起来了

image.png0609aa2.gif

我们再给太阳加点效果,让它周围有一闪一闪的阳光,所谓阳光其实就是均匀分布在太阳周围并指向太阳圆心的直线,那么先创建一个list来放绘制直线的角度

image.png

这个角度用来干什么用的呢?就是用来计算绘制直线时候startend的xy坐标,计算坐标的函数如下

image.png

pointXpointY分别是计算x坐标与y坐标的函数,第一个参数是点与圆心的距离,第二个参数分别是圆心中心点的x坐标与y坐标,第三个参数就是角度,那么现在就可以写绘制阳光的代码了

image.png0609aa3.gif

阳光出来了,还差一闪一闪的效果,这个效果其实就是阳光的直线变长变短的循环动画,循环的对象就是直线最长与最短的长度差,有了刚刚下雨的铺垫,我们这个循环动画马上就出来了

image.png

lightDis就是阳光长度的差,我们在刚刚绘制直线的代码中使用这个变量

image.png

阳光的代码就全都结束了,现在我们就让阳光闪动起来

0609aa4.gif

白云

刚刚我们绘制过乌云,几个椭圆拼起来就达到乌云的效果了,但是白云不能用同样的方法,毕竟大晴天天上也密密麻麻那么多白云的话,那瞅着又要下雨了,那怎么画呢?我们依然还是先画一个椭圆

image.pngimage.png

然后在椭圆上再连着画三个相连的圆,目的就是让四周都有个圆弧,达到看起来像个云朵一样效果

image.pngimage.png

一个云朵就画出来了,不难吧?我们给这朵云来点效果,让它可以飘动起来,怎么飘动呢?由于绘制云朵的时候,无论是椭圆还是三个圆,所在位置的x坐标都是width.value * 2 / 3,那么我们只需要改变这个值,就可以起到让云动起来的效果了,这里我们又一次使用到了循环动画,循环改变x的值

image.png

cloudCenter就是循环改变的x值,现在就将这个值代入到绘制云朵的代码中,让它取代原来的width.value * 2 / 3

image.pngimage.png

我们的白云也动起来了,效果如下

0609aa5.gif

彩虹

下完雨的天气,应该大概率会出现个彩虹,那么我们这里也整个彩虹出来,彩虹我们可以把它看成是七个不同颜色的扇形组合在一起,扇形的大小以及左上角的坐标由外到内是根据单个扇形的粗细来递减的,所以我们需要如下几个变量来绘制扇形

image.png

  • singleWidth:单个扇形的粗细
  • circleRdius:扇形的半径
  • colorList:所有扇形的颜色

绘制扇形需要用到drawArc函数,绘制七个扇形的代码如下所示

image.pngimage.png

彩虹的样子就已经画出来了,但现在的彩虹还只是静止的,我们希望让彩虹也可以动起来,并且是在太阳出来以后开始动,比如从右边开始慢慢的展开,那么对于这个扇形来说就是sweepAngle从0到-180度的过程,所以我们给这个过程设置个开关以及角度变化的动画

image.png

rainbowState就是彩虹动画的开关,并且在太阳动画结束以后开启,开启以后彩虹sweepAngle的角度就从0展开至-180度,现在我们把sweepAngle代入到绘制彩虹的drawArc函数里面

image.png

现在再运行一遍代码,整个晴天的动画过程就出来了

0609aa6.gif

雨过天晴

现在就是最后一步,需要将我们之前做的下雨天跟晴天连在一起,由于这两个过程我们都做在单独的Composable函数里面,所以这里可以使用AnimatedVisibility来做转场的切换,我们知道AnimatedVisibility只有当第一个参数visible为true的时候,才会展示content,所以这里展示下雨天和晴天也是需要一个开关来控制

image.png

sunnyState就是一个控制下雨天与晴天的开关,这里还设置了一个定时器,三秒以后触发转场,隐藏下雨天,显示晴天,转场代码如下

image.png

现在我们整个雨过天晴的过程就完成了,最后看下效果

0609aa7.gif

总结

这篇文章没有什么难点,都是些基本的Canvas绘图技巧和动画知识,主要是最近实在被这天气给整郁闷了,所以才做了这么一个小demo,算是娱乐一下,希望这天气赶紧结束吧。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYAa00KA' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片