An animation loading implementation and an animation loading implementation
I remember seeing an animation design above, and I tried to implement it. First, we can see that the animation is composed of two parts, one circle rotates clockwise, and the other is the linear movement of dots, there is a time difference between the dots, and the superposition of the two motion forms this rolling effect.
Figure 1, Figure 2, and figure 3
Figure 1 shows the status of circle rotation, Figure 2 shows the status of linear movement of dots, and Figure 3 shows the effect of time difference between dots added in Figure 2.
Draw points
There are 15 dots in total, and the phase deviation is 360/15 = 24 Gb/s.
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;}private final double DEGREE = Math.PI / 180;private static final int POINT_NUM = 15;
ArcPoint is the point definition, including position and color.
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; }}
Draw circle Rotation
It can be fixed without moving points, and implemented by rotating the canvas.
@Override protected void 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(); } }
In this way, we can get an animation with a circle rotation. The rotation angle is fixed here.36, If yes360You can see a complete rotation.
Why is the rotation angle here?36? To see the complete effect, each point is actually rotated after moving in a straight line.1.5Phase deviation, that is24*1.5=36It can overlap with the actual dot graph, and because the dot color is repeated every three times, after 36 degrees of rotation, the new dot position and the starting state of the animation look the same.
Add start offset time to the dot
The start time of each point movement is different. If we move together, we will get the effect of Figure 2. We can see how to get the moving time of each point from the total time, that is
float itemFactor = getItemFactor(i, factor);
private float getItemFactor(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);}
The time for linear motion of each point is designed to be periodic.1/3, The remaining2/3=0.66The time from the first point to the last point.
factor - 0.66f / POINT_NUM * index
You can get the start time of each dot.*3Converts it to the time when the linear motion occurs.
Combine the above motion to get the completeonDrawMethod
@Override protected void 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 source code here