用Compose又做了三个挺吼看的loading动效

最近又新做了三个Loading,不多,但都是自己原创的,代码已经上传了,有兴趣的小伙伴可以clone下来看看,下面就介绍下这三个Loading的制作过程,同样的,大家可以选择感兴趣的loading来看。

源码地址

万花筒loading

这个loading看起来花里胡哨的,其实做起来还是蛮容易的,主要是用到了BlendMode这个参数,老规矩,我们绘制动画第一步,首先将需要的变量创建好

画布的宽width,画布的高height,以及圆周运动必需品中心点坐标centerXcenterY,接着来做几个绕着中心点转圈的圆,我们知道画圆主要的就是确定好它的center的位置,center就是个Offset,所以这里创建个数组用来存放这些圆的Offset

offsetList就是用来存放Offset的数组,pointXpointY是通过半径,中心点,角度来计算目标点坐标的函数,不多做介绍了,源码里面有,这里可以看到总共有十个Offset,对应了十个圆,每个圆的圆心距离中心点坐标60f,圆与圆之间的角度偏移量是36f,刚好平分整个圆周空间,我们接下来遍历offsetList来将十个圆画出来

我们看到圆的半径居然也要50f,那画出来的效果不就十个圆基本挤在一起了吗,我们看下效果

根本就看不出来圆嘛,其实这个才是我们想要实现效果的第一步,先将圆都重叠在一起,接下来就是主角BlendMode登场了,可能有些小伙伴对这个还比较陌生,没见过啊,其实它在我们使用DrawScope里面的api的时候就已经出现过了,基本每一个drawXXX的函数的参数列表里面,最后一个参数就有它的身影,比如在这里要使用的drawCircle函数里面

我们看注释里面的Blendmode的描述就是Blending algorithm,一种混合算法,也就是在绘制时候将绘制的图形像素与Canvas上对应位置的像素进行混合形成新的像素,类似于传统Android里面的PorterDuff,基本PorterDuff里面的模式Blendmode都有,同时Blendmode还有一些自己的模式,其中引起我注意的就是Plus模式

我们可以看到注释里面对这个模式的描述是重叠部分的像素的透明度会降低,也就看起来像是该部分的颜色变深了一样,那么对于我们demo中十个圆刚好就是处于重叠状态,我们使用这个模式会出现什么现象呢,来试试看

怎么感觉没啥变化?其实是有变化的,Plus模式的注释可能看起来比较难以理解,其实最好理解的方式就是从这个模式命名本身出发,Plus模式意思是加模式,就是将两个重叠涂层的十六进制色值加一起,而我们这里用的是Color.Red,色值为0xFFFF0000,排除前面的透明值通道,这里就是首先对两个FF0000进行十六进制的加法,算出来的结果如下所示

得到的是FE0000,可不就还是红色嘛,虽然色值不同,但是用肉眼自然没法区分开来,我们再看看将FE0000FF0000相加得到的是什么

FD0000,色值不同但依然还是红色,所以这里的例子我们不能用Color.Red,换个色值试试,比如FF1D1D这个色值,再看看效果如何

我们看到重叠部分的色值已经发生了变化了,多次重叠以后,整体就看起来像一朵红花一样,那么我们已经给十个重叠的圆加好了混合模式,因为做的是万花筒效果,所以颜色得多一些,这里再多加几个颜色,并且定时切换

比如这里有六种颜色,接着使用循环动画不断取这个colorList的下标值,然后通过animateColorAsState函数切换下标值对应的颜色,代码如下

color作为绘制十个圆的色值以后,效果就出来了

效果如何?我们接着再给这十个圆加点动效,比如绕着中心转动,并且十个圆与圆心距离有个渐近渐远的过程,那么再新建两个循环动画

然后再将diffAnglediffDis这俩值参与到计算十个圆的Offset的数组当中

我们这个万花筒的Loading效果就做出来了,最终效果图如下

转动的蜂窝碎片

这个是从上一篇蜂窝墙那里做完以后想到的,我们绘制蜂窝墙的时候,绘制范围是铺满整个画布的,蜂窝墙整体其实就是个长方形,所以我们可以通过等分画布宽高来找出坐标点来绘制一个个蜂窝格子,但是如果是要画其中一小部分,就要用另一种方式,从中间向外画,我们来看下如何做,首先还是将一些必要的变量创建出来

基本跟上面的万花筒一样,多了一个sideWidth,表示一个六边形的边长,多了三个list,xListyList是用来存放所有需要绘制的六边形的中心点,anglist是绘制六边形六条边的时候需要的角度,pathList是存放需要绘制六边形需要用到的Path,那么先在中心位置画一个六边形来练练手,在xListyList中分别放入中心点坐标centerXcenterY,然后通过遍历xListCanvas中将每个点对应的六条边画出来,代码如下

中间这个六边形画好了,然后给这个六边形的六条边对应的方向也画上六边形,那么第一步,算出周围六边形的中心点与已经画好的六边形的中心点之间的距离,我们用勾股定理就能得出

然后是六个中心点的角度

现在就可以在xListyList中加入六个点的坐标了

由于之前就已经在Canvas中加入了遍历xList绘制六边形的代码了,所以这里直接就能获得另外六个六边形

一个小的蜂窝碎片就做出来了,简单不,我们继续添加些坐标,把这个蜂窝碎片弄的大些

接下来就是上色了,上色的第一步还是先填充满蜂窝的小格子,也就是需要绘制一些六边形样式,这里创建一个pathList来存放绘制六边形需要的Path,然后遍历xList或者yList来生成一个个PathaddpathList里面去

然后在Canvas中遍历生成的pathList,并使用drawPath函数绘制出一个个六边形

效果就出来了,然后我们多创建几个颜色,并且使用animateColorAsState函数来切换

Canvas中将color作为绘制六边形的颜色值,我们就得到了一个颜色可变的蜂窝碎片

还剩下最后一步让这个碎片转动起来,也就是让我们的Canvas转动起来,如何转动呢?就需要用到Modifier的一个操作符graphicsLayer,它里面有控制x,y,z轴转动的参数,分别是rotationXrotationYrotationZ,比如我们想要让它绕着x轴转圈,那么就需要有个0到360度变化的动画过程

然后将canvasAngle赋值给graphicsLayerrotationX参数,我们的碎片就转起来了

我们还可以把canvasAngle作用在roatationYrotationZ上面,让它再其他方向也有转动的效果,不过这里打算再新建两个转动的变量,目的是让这三个方向转动的角度速率都不一样,代码如下

转动的几何图形

说实话这个能不能叫Loading我也不知道,只是忽然有个想法想试试看,之前画过几个贝塞尔曲线,但都是偏向简单的,一根两个组合在一起使用的那种,那么如果是许多根贝塞尔曲线在一起,会有什么效果呢,所以就试了一下,一些准备工作就简单带过了,直接上代码

我们知道画贝塞尔曲线需要几个控制点,三个控制点构成一个二阶曲线,四个控制点构成一个三阶曲线以此类推,我们这里按照控制点顺序分别命名为P0,P1,P2....那么如果在一个圆周上,有count个点作为P0点,在另外一个圆周上也有count个点作为P1,然后同样在另外一个圆周上有count个P2的点,最后将每个圆周上对应下标值的点组合成一个二阶曲线,我们看看会出现个怎样的图形

count是需要绘制的曲线个数,unitAngle是圆周上的点间隔的单位角度,baseRadius是P0点的圆周的半径,后面的圆周的半径都是在baseRadius上做增加或减少,然后新建了六个list,分别存放P0,P1,P2的xy坐标,我们可以看到计算P1,P2点的坐标的半径与角度都与P0有一些区别,然后新建一个pathList用来存放二阶曲线的Path,然后在Canvas中遍历这个pathList将所有Path绘制出来

这里在绘制的时候还加上了混合模式,目的是让重叠的地方颜色可以变换一下,达到整体立体的感觉,效果就是下面这样

这是我们画二阶曲线的效果,这里再增加一组控制点,将二阶变成三阶再看看效果

跟上面的效果比起来又有点膨胀的感觉,这里我们发现了,每一组控制点在计算的时候,角度那一部分该变量都是一个定值,比如it * unitAngle+80f, 那么如果我们将这个定值变成一个可变值,会有什么效果呢?

比如这里有一个60度到300度的一个变化动画,我们将angleDiff代入到计算控制点的代码中

这里给除P0外的控制点,在计算x或者y坐标中,横坐标对angleDiff做了除法,分母是控制点下标值加一,纵坐标对angleDiff做了乘法,乘上的也是控制点下标值加一,这些值都是自定义的,大家可以按照自己喜好来定,现在运行一遍看看效果图

我们就得到了一个会转动的立体图形,这里并没有像上面那个蜂窝碎片一样调用rotationX或者rotationY来实现立体转动效果,而是让若干条贝塞尔曲线不断更改绘制角度从而来实现这样的一种视觉效果,这样的思路可能会对以后做其他效果会产生一些帮助,言归正传,现在画出来的是三阶曲线,那能不能在多画几阶呢,想看看多阶曲线能产生什么样的效果,可以的,很容易,再调用一次cubicTo函数就好了,那么我们需要再多创建三组控制点

然后将这三组新的控制点代入到另一个cubicTo函数

就这样做出来了一点科技感的味道在里面,最后再稍微给这个效果美化一下,加点渐变色,另外给Path加点dashPathEffect的效果

最终一个好看但不实用的loading就做好了~

总结

这次做的三个loading效果虽说实用性不大,但是还是用到了一些绘图的小技巧,比如混合模式之类的,可能会在今后的开发中对自己有所帮助。

相关推荐
腾讯TNTWeb前端团队3 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
peakmain96 小时前
Jetpack Compose UI组件封装(一)
android jetpack
范文杰6 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪6 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪6 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy7 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom8 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom8 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom8 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom8 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试