效果图:
目录
实现这个动画需要的一些预备知识:
一、使用canvas的旋转
在绘制刻度的时候,会涉及到旋转操作,此处将一个圆分成100分,那么每一份就是3.6f;
canvas.rotate(旋转的角度,旋转中心X,旋转中心Y);
因为是画布的旋转,那么会导致画布整体旋转,所以需要在旋转之前保存之前的位置(使用canvas.save());
然后再旋转完成之后再恢复之前的状态(使用canvas.restore())
二、画布Canvas.clipPath()方法。
因为绘制上面的进度条外层其实是一个矩形框,那么我们可以使用clipPath()方法来剪切,剪切成一个圆,这样就可以显示成动画再圆中;
详细介绍请见:
canvas常用的方法【重点】:
三、实现思路
1、外层的刻度进度条:
使用一个循环,当当前的值i小于mPercent的时候就改变画笔的值,设置为进度条的颜色,否则就设置成刻度背景颜色;然后通过旋转分别绘制100条短线段;
2、里面的水波纹的操作
水波纹的操作主要使用的是:贝塞尔二阶曲线;
那么如何实现水波了,其实就是不断的从一个方向绘制贝塞尔曲线,然后添加一个进步mStep,当从右向左绘制的时候,不断的改变贝赛尔曲线的控制点的x和Y轴的值和每一个quaTo()的后面结尾的那个店的x轴的值;
四、自定义属性并初始化属性
五、绘制外层刻度条
六、根据当前的进度改变水波纹的振幅
为什么要改变振幅,那是因为当进度比较小的时候(比如<20),需要将振幅变小一些使得看着平滑一些,当进度比较大的时候可以稍微变大,当进度过大(比如大于>80),进度有已经在顶部了,那么也需要将振幅变小使得看着平滑一些;
里面的参数可以在适当的修改。
七、绘制水波纹及原理【重点】
1、获取到水波中心点Y轴的值
绘制水波纹,根据前面画的图,首先必须知道水波纹中心点的Y轴坐标值;Y轴的坐标值是随着进度变大而变小的;
Y轴的值=水波圆高度*(1-mPercent/100)+刻度的长度+刻度圆和水波圆的间距;
2、创建一个水波圆,并使用画布剪切
之所以要使用画布剪切是为了让绘制的水波纹在圆内显示出来。
canvas常用的方法【重点】:
3、绘制贝塞尔曲线:
(1)为什么贝塞尔曲线控制点的x轴-mStep?:
因为是绘制从左到右,那么减去在每一个贝塞尔曲线的控制点的x-mStep,就达到了,水波纹从右向左移动的目的;
(2)为什么要判断是否是奇数和偶数?
因为在绘制贝塞尔曲线的时候,当当前绘制的曲线(quadTo())的时候为奇数 的时候,驼峰向上那么Y轴就应该减去振幅,当为偶数的时候,驼峰向下那么Y轴应该加上振幅。
(3)为什么绘制的贝塞尔曲线会大于mWaveCount?
此处本人绘制的是2倍的mWaveCount;
首先来看一下:绘制成mWaveCount数量的贝塞尔曲线会是什么样子?
此处我将剪切圆也注释掉了,这样更加清晰的看的出来。
水波纹产生的情况是右边一直往左边推动或者说是偏移,而左边也产偏移,从而产生波纹;
当绘制成mWaveCount数量的贝塞尔曲线的时候,右边部分产生了空缺从而在视觉上有停顿的效果;那么如果我们把绘制的位置往右多绘制几个,那么在不可见的区域即使有停顿也不知道了。
现在把绘制成2倍的mWaveCount数量:
可以看得出来,早可见的区域就是一个无限的动画效果。具体的停顿就在不可见的区域了。
4、同理可以绘制第二个反向的水波纹
在绘制反向的水波纹的时候需要注意的是:
1、因为往右移动(那么相当于x轴的值一直在加);
2、关键是,因为现在需要过渡在左边绘制,以填补左边的空白
五、为水波纹和进度条添加移动属性动画
六、绘制进度条文字
项目地址: