记住以前用的Windows电脑里边,有一个屏保程序便是在屏幕上呈现许多飘来飘去的球,当球碰到电脑边际的时分,会反弹到相反的方向,然后最近就揣摩着能不能运用Compose DeskTop也完结一个这样的作用,那今后我的Mac屏幕上也能呈现很多小球,那简直是泰裤辣~
规划思路
咱们把全体动效拆分一下一共有五步,每一步都不是很难
- 第一步:运用循环动画不断改动小球位移的x坐标与y坐标,x坐标的改动规模是0到窗口宽度的最大值,y坐标的改动规模是0到窗口高度的最大值
- 第二步:判别当x,y坐标抵达自己的最大值的鸿沟值的时分,将各自的改动规模的初始值与终究值互相对换一下,抵达往相反方向移动的作用
- 第三步:经过改动
tween
函数的durationMillis
和easing
特点,来改动小球的位移速度与位移道路- 第四步:将小球的动画需求的特点作为函数的入参,抵达能够在上层定制小球动画的作用
- 第五步:将窗口的宽度与高度更改成屏幕的宽高,背景色改成通明
让球动起来
首要咱们来把球的款式做出来,球本身便是个圆形,咱们运用Surface
组件就能够完结,里边再包一个Box
组件,这样做的意图是由于Surface
没有办法设置渐变的背景色,咱们假如想要让圆形看起来立体一些,就需求让背景色带点渐变,所以渐变的工作就交给里边的Box
组件来完结
然后就能够把这个球放到咱们的窗口里边去了,在这之前咱们先创立三个常量,别离是窗口的宽高最大值以及小球的巨细
然后把这三个常量别离设置给Window
组件以及ball
组件,代码与作用就如下图所示
接下去便是让这个球动起来了,咱们经过改动球的位移坐标来完结球体的移动,这儿给位移坐标的x,y别离设置一个无限循环动画,动画的初始值是为0,目标值为窗口的宽高,动画时刻设置为5秒,然后让这个动画进程线性改动,完结进程如下所示
咱们给Surface组件添加了offset
操作符,让它接纳mainx
与mainy
的改动值,咱们这个球就动起来了
改动位移方向
现在现已让球动起来了,接下来便是要考虑如何让球“碰壁”今后反弹,由于咱们的初始方位在窗口左上角,所以咱们能够先做碰到下面今后的反弹以及碰到右边今后的反弹,也便是当x坐标抵达或许挨近x轴位移的最大值,或许y坐标抵达或许挨近y轴的位移最大值今后,咱们将mainx
与mainy
的初始值与目标值对调一下,这样就能往相反方向移动了,留意这儿说的是位移最大值,不是窗口的宽高,由于球位移坐标是从球的左上角开端核算的,当碰到窗口鸿沟的时分,其实位移间隔是窗口的宽高减去小球的直径巨细,所以咱们再加上两个常量作为位移的最大值,方便后边核算时运用
然后假如想要在无限循环动画里边改动初始值与目标值,咱们就要运用Animatable
来切换,所以这儿再创立四个Animatable
的变量,别离代表x,y轴的初始值与目标值
创立好了今后,就直接把mainx
与mainy
的初始值与目标值替换成了新建的四个Animatable
变量,这样当咱们去切换它们的值今后,mainx
与mainy
的改动规模也发生了改动,而Animatable
的切换函数snapTo
是一个挂起函数,所以还需求一个协程作用域,咱们这儿运用rememberCoroutineScope
函数来创立,那么小球碰到窗口下边与右边的反弹代码就有了
这边判别抵达鸿沟的条件不是mainx.value.value == offsetx.value
的原因是由于经过打印日志发现,mainx
或许mainy
的改动值不会一直刚好是offsetX.value
或许offsetY.value
,所以只能把判别当两个值挨近的时分当作小球移动到鸿沟的条件,咱们运行下看看反弹作用
动图上看不出来,实际作用其实抵达鸿沟时分有点纤细的抖动,这也跟咱们刚刚那个鸿沟值的判别条件有关,不过也不影响功能,咱们依照这个方法把碰到左边与上边的代码也加上,一个完好的球体移动动画就做好了
现在现已能够完结小球碰到窗口四周反弹的作用了,可是完结方法仍是比较繁琐的,又是协程又是切换又是看鸿沟值的,咱们其实还有更简单的办法,由于不管是x轴的值仍是y轴的值,它的改动规模一直在两个值之间,差别便是每次起始方位不同,那么这便是一个重复的进程,而咱们这个循环动画其实就能够设置重复形式,运用repeatMode
特点,值取RepeatMode.Reverse
就能够了,咱们试一下
咱们看到现在咱们把那四个Animatable
都去掉了,mainx
与mainy
的初始值与目标值又回到了固定值,区别便是增加了repeatMode
,现在咱们在看下完结作用咋样
看起来好像差别不大,但其实碰到鸿沟后的作用比之前要很多了,由于不用去关怀那一点误差,并且也能够随意设置动画时刻,之前为了让动画的改动值不要改动的太大,所以动画时刻我是最小只能设置成5秒,现在的动效看起来就舒服多了
改动速度与道路
动画速度的话咱们刚刚其完成已完结了,经过改动动画时刻durationMills
来完结,可是由于咱们的easing
设置的是LinearEasing
线性改动,所以小球的位移道路永远都是沿着一根直线移动的,咱们能够经过改动easing
的值,来改动小球的位移道路,比方现在我将easing
改成FastOutSlowInEasing
得到的作用便是这样的
这球一会儿就变得好像“有智商”了一样,感觉要“撞了”就马上减速,然后换个方向持续飘
特点作为参数,让小球可定制
想要定制小球动画的话,首要要确定好哪些特点能够拿出来定制,经过上面的开发,咱们这个小球动画能够被定制的特点有以下几个
- ballSize:小球的巨细
- ballColor:小球的色彩
- xTime:小球位移x轴上的动画时刻
- yTime:小球位移y轴上的动画时刻
- xAnimateEasing:小球x轴上动画的改动速度
- yAnimateEasing:小球y轴上动画的改动速度
这姿态的话咱们ball
函数的参数列表就如下所示
然后再将代码中的对应方位用参数来替代
咱们这儿把核算最大位移的过程也移到函数里边了,这样就能够依据不同的小球巨细来核算各自的位移间隔,咱们这个ball
函数到这儿算是完结了,现在咱们就能够想弄几个小球就弄几个小球了,比方我这边就弄了这么几个小球
下面便是一堆小球的作用
咱们再改下小球的款式,将小球弄成背景有点通明的姿态,让飘动的小球看起来像是气泡一样,改完今后的小球代码如下
然后再将调用ball
函数的地方,ballColor
的入参也改成带点通明值
如作用图所示,是不是有那么点意思了呢,现在咱们进行终究一步。
将窗口通明,宽高增大为全屏
想要将窗口弄成通明的话,能够运用Window
组件的transparent
和undecorated
特点,代码如下
然后把screenWidth
与screenHeight
巨细设置成全屏巨细就能够了,咱们运用ToolKit
来获取屏幕宽高
还差一步,由于到了这儿就算screenWidth
和screenHeight
设置成全屏宽高了,但实际上地点的窗口并没有真正的全屏,它跟屏幕左边留有一点间隔,然后右边延伸至屏幕外边了,所以咱们需求让整个窗口居中显现,运用WindowPosition
,这个是WindowState
里边的一个参数,咱们在WindowPosition
中设置成居中对齐就能够了
终究咱们得到的作用便是这样的
总结
全体作用完结起来仍是蛮简单的,一共代码加一块也不到一百行,感觉把Window
设置成通明今后,DeskTop开发变得好玩多了,我们有兴趣的也能够测验下,所有元素都能够依照自己喜好来定制,去规划属于自己的屏保程序