赞
踩
最近杂七杂八的事情一堆,忽然发现自己好久没有写Compose了,最近的一篇Compose相关的文章离现在差不多快要两个月了,这么一想可把自己吓一跳,那么长时间了可别把Compose的东西给弄生疏了呀,尤其最近又是ArkTS又是React的,都是声明式的语法又那么接近,在不写点Compose估计就要不会写了,那么该写点啥呢?之前前前后后整了有十六个Compose的loading动效,发现做动效还挺有意思的,那么这次继续来做点动效吧,但不做loading了,做点进度动效来换换口味,打开IDE,开整~
之前网上去搜了一下,这样的动效大多数都很千篇一律,基本都是中间一个百分比数字,周围一个圆弧,从一个小圆弧变成一个完整的圆,这样整个动效就结束了,有差异的也最多就是字体颜色,圆弧颜色,圆弧粗细之类的不一样,但是这样就很枯燥,我们这次就来做点有意思的,不一样的动效来看看,首先不管是什么样的效果,咱都需要一些数据来表示进度,这个进度就用下面这段代码来实现
一个状态变量progress
,这个变量就是用来保存当前的进度,并且作为LaunchedEffect
的key,首次启动,LaunchedEffect
会执行它内部的协程block
,block
里面是一个Flow
,Flow
的上游判断当前progress
的大小是否超过了100,超过了就重新置成0,没有超过的话就延迟200毫秒再emit
个2到下游,下游拿到上游发送过来的数据之后,更新到progress
上,然后重新触发LaunchedEffect
执行新的协程block
,就这样一个简单的改变进度的过程就做好了,后面只需要将progress
传递给每个动效函数就好了,下面来做第一个动效
这个动效是之前在别的地方看到过,也是百分比跟圆弧的组合,但是圆弧除了弧度会变大之外,圆弧本身也会绕着百分比旋转,这边也来用Compose实现一下,由于要展示百分比数字,所以整个布局结构是外层一个Box
,里面是一个Canvas
和一个Text
,Canvas
用来绘制圆弧部分,Text
用来显示百分比,整个结构如下
Text
直接展示的就是进度的值progress
,然后将RollingArc
函数在外层Window
函数中调用后的效果就如下所示
然后由于项目用的Compose版本是1.5.1
众所周知,Compose在1.4的版本里面已经给文本组件添加了drawStyle
属性,可以轻松给文本设置上描边效果,实现起来也很容易,只要在Text
组件中设置了drawStyle
属性就好,样式就在里面自定义
上面这段代码就是给Text
增加了一个描边效果,其中边的粗细是3f,笔触设置为StrokeCap.Square
,效果就像下面这样
文本现在就呈现出只有描边,中间是空心的效果,drawStyle
还可以设置其他效果,比如给文本设置虚线效果之类的,但不是本文重点就不说了,大家有兴趣可以尝试下,我们继续下一步,现在做好了百分比的跳动动画,然后就是外面的圆弧动画了,这个就要在Canvas
里面使用drawArc
函数来完成,我们先随便画个圆弧,比如起始角度是0度,弧度大小是90度,代码如下
这里画了一个弧度粗细是30f,位置在左上角(0,0)坐标,大小是100f * 100f的圆弧,大概的样子就像下面这样
现在要挪动这个圆弧,让圆弧的圆心刚好是整个画布的中心,那么圆弧就能绕着中间的百分比数字旋转的了,那么第一步,需要定义几个变量
代表中心点坐标的centerX
与centerY
,以及圆弧半径outRadius
,有了这三个变量,就可以计算出当圆弧圆心在画布中心时候,topLeft
的x,y坐标,代码如下
左上角x坐标就是centerX
减去圆弧半径,y坐标就是centerY
减去圆弧半径,而Size
里面就是传入圆弧的直径,也就是两倍的outRadius
,这个时候圆弧的位置就在画布中间了
接着就是动画部分,先让圆弧绕着中心旋转,这个很简单,让startAngle
的值变成一个循环改变的动画变量就好
然后把start
作为startAngle
的值,圆弧就转起来了
圆弧转起来以后,圆弧的弧度就得跟着传进来的progress
值动态改变了,直到progress
值是100的时候,圆弧的弧度就变成360度,这里progress
与sweepAngle
的转换关系是这样的
我们把这个转换关系代入到drawArc
的sweepAngle
里面去,圆弧的弧度也就跟着progress
一起改变了
这里不知道大家有没有看清,这个弧度改变的过程中有点卡顿,主要原因是我们sweepAngle
的值改变的时候是从一个值直接到另一个值,没有一个过渡的过程,才会让效果看起来有点卡顿的样子,解决这个问题也很容易,我们让sweepAngle
也变成一个动画变量就好,使用animateFloatAsState
函数来实现
这里将progress * 3.6
作为targetValue
值代入到animateFloatAsState
函数里面去,这样就得到了一个sweepDif
的改变动画,我们将sweepDif
代入到sweepAngle
里去后,再来看下效果
现在sweepAngle
改变的时候卡顿的感觉就不是很明显了,而这个动效也基本完成了,剩下的事情就是美化工作,让百分比字体颜色与圆弧颜色随着进度的改变有个颜色的过渡变化,要做到这一点的话首先需要一个颜色的数组
这里创建了一个颜色数组circleColorList
,长度大小是11,为什么是11呢,因为我们进度progress
的取值是从0-100,这些数字的十位数是0-10总共有11个,每一个十位数如果要对应一个颜色的话,那么肯定的我们这个数组长度就必须设置为11,然后再使用animateColorAsState
函数创建一个颜色改变的动画
可以看到这边的targetValue
取的就是circleColorList
里面的值,下标是progress/10
,然后再把ringColor
作为我们圆弧与百分比字体的颜色,整个动效就多了一个颜色切换的效果了
这里还给颜色加了点渐变,最终整个动效就完成了
可能这里会有小伙伴吐槽,你开头不是说圆弧的动效比较枯燥,看腻了吗,怎么自己反手就做了个圆弧呢?piapia打脸了昂,好吧。。刚开始手有点生疏,所以先做个中规中矩的热热身,接下来就开始做个有意思的,这里重新再新建个函数
这里一样创建了中心点坐标centerX
与centerY
,可以从函数名字可以看出,这次要做的动效是要去画线,当然这线不是去调用drawLine
函数去画,而是画的是贝塞尔曲线,我们都知道画贝塞尔曲线其实就是绘制Path
,所以我们也要去绘制Path
,绘制很多Path
,所以先创建一个存放Path
的数组
直接创建了一个大小是100的数组,里面也创建了100个Path
,但是并没有定义具体路径,因为不同的路径所展示出来的效果也都是不一样的,比如我们这里要画的曲线是二阶的,二阶曲线的首尾控制点都在一个圆上,第一个控制点比如是在圆的0度位置,那么最后一个控制点则是在相对于第一个点再经过90度的位置,至于中间的控制点,就是在比首尾点所在的圆更大的圆上,位置就是在0和90度之间,其他曲线也都这样的逻辑,只是控制点所在的位置的角度呈递增关系,大概的绘制思路就是这样,我们现在就来将这一百个曲线绘制出来,由于有两个圆,所以再创建两个变量代表这两个圆的半径
maxRadius
是比较小的圆的半径,outRadius
是较大圆的半径,由于要获取圆上点的坐标,所以再创建两个函数分别去计算坐标的x,y值
两个函数所需要的参数里面,半径与中心点坐标都有了,还缺第三个参数角度,由于Path
数组大小是100,所以我们将整个圆周等分为100份,每一个小圆弧跨越的角度都是3.6f,那么所有曲线的第一个控制点就有了
第二个控制点在比较大的圆上,所以半径需要使用outRadius
,角度可以是在第一个点的角度基础上加上随便一个0到90度的值,比如45度,那么第二个点的代码如下
第三个控制点的半径又变成了maxRadius
,角度是在第一个点的基础上加上90,所以完整的贝塞尔曲线的路径的代码如下
现在就可以在Canvas
里面遍历pathList
,将所有曲线绘制出来了,绘制代码如下
然后我们就能得到下面这样的图案
现在是将所有曲线都绘制出来,如果想要让绘制的曲线数量与进度progress
绑定在一起,只需要在遍历时候判断一下下标index
比当前progress
小,满足条件的再去绘制就可以了,更改一下代码
这个时候所有曲线都可以去动态绘制了,看下效果
接下来在这个基础上再优化一下,我们给曲线设置个虚线效果,并且透明度让它随着进度慢慢增加,虚线的话可以通过设置pathEffect
属性去实现,透明度直接用progress/100f
,不过要判断下值,不能超出1f,不然程序就闪退了,更改后的代码如下
这个时候的效果再来看下
像不像一个钢丝球?我们给这个“钢丝球”染个色,先定义一组色值
然后在绘制Path
的地方,用brush
属性代替color
属性将这组色值设置进去
现在的“钢丝球”就变成彩色的了
这个动效做到这里其实可以收工了,但是总感觉哪里还缺点啥?代码往上翻一翻可以发现这段代码
这是定义曲线路径的代码,其中第二个控制点的位置现在还是固定在距第一个点45度的位置,我们可以在这个值上下点功夫,比如下标为偶数的点,计算x坐标的角度为45度,计算y轴角度为55度,下标为奇数的则反过来,代码更改下就是下面这样
我们看看现在效果变成什么样子了
“钢丝球”一下子变得就有层次感了,如果想要把百分比的文本也显示出来,可以使用drawText
函数,在“钢丝球”中间展示百分比文本,代码如下
具体效果就是下面这样
这篇文章里总共做了两个进度动效,一个算是比较务实,实用的,一个则比较抽象,创意元素多一些,不过目的还是为了打破那种墨守成规的思路,不一定进度动效只能设计出那种圆环,或者进度条的样式,也可以多发挥想象力,设计出更加好看,酷炫的进度效果。
作者:Coffeeee
链接:https://juejin.cn/post/7281911124806664233
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。