相关文章推荐
失望的篮球  ·  ElementUI 中el-popover ...·  1 年前    · 
有腹肌的扁豆  ·  爆破专栏丨Spring ...·  1 年前    · 
indicator-03.gif

注意:为实现上面链接中所示的动画,首先确定,两个圆随着偏移量的改变,半径大小出现了变化,同时贝塞尔曲线有所变化,那剩下的问题就是如何改变两个圆的半径大小,圆的位置,同时计算和绘制贝塞尔曲线

接下来看具体的实现#

首先偏移量###

我此处给的值比较简单,直接通过 SeekBar 来获取偏移量
获取偏移量后,需要改变的数据有,半径大小,以及第二个圆的位置,以及贝塞尔曲线的重新绘制
具体代码如下:

    mEndCircle.setX(dpToPx(mDefaultFirstX + mMaxDistance * offset,getResources()));//修改第二个圆的位置
    mEndCircle.setRadius(dpToPx(mDefaultMinRadius,getResources()) + offset * dpToPx(mDefaultMaxRadius - mDefaultMinRadius,getResources()));//第二个圆半径变大
    mStartCircle.setRadius(dpToPx(mDefaultMaxRadius,getResources()) - offset * dpToPx(mDefaultMaxRadius - mDefaultMinRadius,getResources()));//第一个圆半径变小
    mCanDrawBezier = calculatePoint(mStartCircle, mEndCircle);//计算贝塞尔曲线
    invalidate();//刷新,触发onDraw(),重新绘制

然后是计算贝塞尔曲线###

看下图,基本上可以确定出有两条曲线,我没有画两条曲线,而是一条mBezierPath搞定
A->B->C->D->A(关于控制点哦o,p后面会有计算分析,基本按照上图中所写就可以计算出o,p两点的位置)

14-51-38.jpg

其中,A点是开始点,直接 moveTo() 即可,然后用lineTo()到B点,再调用系统自带的贝塞尔曲线方法quadTo(ponitP.x,pointP.y)计算即可,然后就是一样的lineTo()到D点,quadTo(pointO.x,pointP.y);
关于quadTo(x1,y1,x2,y2)的使用,可以去百度一下,简单说一下,就是前面两个是控制点,后面两个是到达的点
这样mBezierPath基本就画好了,然后画起始圆和结束圆就可以了(当然,如果考虑到overdraw的话,起始可以用clipRect clipReject去掉重复的半圆,此处偷懒,直接画了两个圆,没有去掉重复绘制,或者直接画一个半圆,当然半圆的效果和圆是不一样的)
以下是构建出mBezierPath的代码

    mBezierPath.reset();
    mBezierPath.moveTo(mStartA.getX(), mStartA.getY());
    mBezierPath.lineTo(mStartB.getX(), mStartB.getY());
    mBezierPath.quadTo(mControlPointP.getX(), mControlPointP.getY(), mEndC.getX(), mEndC.getY());
    mBezierPath.lineTo(mEndD.getX(), mEndD.getY());