一种加载动画的实现

记得看过上面的一个动画设计,就试着实现了一下,首先是可以看到这个动画由两部分组成,一个圆圈的顺时针转动,另一个是圆点的直线运动,圆点之间有时间差,两种运动叠加就形成了这种滚动的效果。

图一、图二、图三

上面图一显示了只有圆圈旋转的状态,图二是只有圆点直线运动的状态,图三是图二中各个圆点添加时间差后的效果。

实现绘制点

这里一共有15个圆点,相位偏差是360/15=24

for (int i = 0; i < POINT_NUM; ++i) {float x = mRadius * -(float) Math.sin(DEGREE * 24 * i);float y = mRadius * -(float) Math.cos(DEGREE * 24 * i);ArcPoint point = new ArcPoint(x, y, COLORS[i % 3]);mArcPoint[i] = point;}DEGREE = Math.PI / 180;POINT_NUM = 15;

ArcPoint是点的定义,包括位置和颜色

static class ArcPoint {float x;float y;int color;ArcPoint(float x, float y, int color) {this.x = x;this.y = y;this.color = color;}}绘制圆圈的旋转

可以固定点不动,通过旋转canvas来实现

(Canvas canvas) {canvas.save();canvas.translate(mCenter.x, mCenter.y);float factor = getFactor();canvas.rotate(36 * factor);float x, y;for (int i = 0; i < POINT_NUM; ++i) {mPaint.setColor(mArcPoint[i].color);// float itemFactor = getItemFactor(i, factor);x = mArcPoint[i].x;// – 2 * mArcPoint[i].x * itemFactor;y = mArcPoint[i].y;// – 2 * mArcPoint[i].y * itemFactor;canvas.drawCircle(x, y, mPointRadius, mPaint);}canvas.restore();if (mStartAnim) {postInvalidate();}}

这样就可以得到图一圆圈旋转的动画,这里固定了旋转角度36,如果是360就可以看到一个完整的旋转。 这里旋转角度为什么取36?看完整效果,其实每个点在直线移动后,转动1.5个相位偏差也就是24*1.5=36,就可以和其实点的图形重合,而且因为圆点的颜色每三个重复一次,所以经过36度的旋转,新圆点位置和动画开始状态看上去就是一样的。

给圆点添加起始偏移时间

每个点运动的起始时间是不同的,如果一起运动就会得到图二的效果,我们看怎么从总的时间得到每个圆点的运动时间,也就是

float itemFactor = getItemFactor(i, factor);(int index, float factor) {float itemFactor = (factor – 0.66f / POINT_NUM * index) * 3;if (itemFactor < 0f) {itemFactor = 0f;} else if (itemFactor > 1f) {itemFactor = 1f;}return mInterpolator.getInterpolation(itemFactor);}

这里设计每个点直线运动的时间是周期的1/3,,那剩余的2/3=0.66就是从第一个点开始到最后一个点开始运动的时间,通过

factor – 0.66f / POINT_NUM * index

就可以得到每个圆点的起始时间,再*3将其换算到直线运动的时间上。 将上面的运动组合起来就得到了完整的onDraw方法

(Canvas canvas) {canvas.save();canvas.translate(mCenter.x, mCenter.y);float factor = getFactor();canvas.rotate(36 * factor);float x, y;for (int i = 0; i < POINT_NUM; ++i) {mPaint.setColor(mArcPoint[i].color);float itemFactor = getItemFactor(i, factor);x = mArcPoint[i].x – 2 * mArcPoint[i].x * itemFactor;y = mArcPoint[i].y – 2 * mArcPoint[i].y * itemFactor;canvas.drawCircle(x, y, mPointRadius, mPaint);}canvas.restore();if (mStartAnim) {postInvalidate();}}Source code

源码在这里 https://github.com/Fichardu/CircleProgress

联系朋友别欠费,天空辽阔任你飞,再多困难别后退! “

一种加载动画的实现

相关文章:

你感兴趣的文章:

标签云: