一種載入動畫的實現,一種載入動畫實現

來源:互聯網
上載者:User

一種載入動畫的實現,一種載入動畫實現

記得看過上面的一個動畫設計,就試著實現了一下,首先是可以看到這個動畫由兩部分組成,一個圓圈的順時針轉動,另一個是圓點的直線運動,圓點之間有時間差,兩種運動疊加就形成了這種滾動的效果。

圖一、圖二、圖三

上面圖一顯示了只有圓圈旋轉的狀態,圖二是只有圓點直線運動的狀態,圖三是圖二中各個圓點添加時間差後的效果。

實現繪製點

這裡一共有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;}private final double DEGREE = Math.PI / 180;private static final int 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來實現

    @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();        }    }

這樣就可以得到圖一圓圈旋轉的動畫,這裡固定了旋轉角度36,如果是360就可以看到一個完整的旋轉。
這裡旋轉角度為什麼取36?看完整效果,其實每個點在直線移動後,轉動1.5個相位偏差也就是24*1.5=36,就可以和其實點的圖形重合,而且因為圓點的顏色每三個重複一次,所以經過36度的旋轉,新圓點位置和動畫開始狀態看上去就是一樣的。

給圓點添加起始位移時間

每個點運動的起始時間是不同的,如果一起運動就會得到圖二的效果,我們看怎麼從總的時間得到每個圓點的運動時間,也就是

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);}

這裡設計每個點直線運動的時間是周期的1/3,那剩餘的2/3=0.66就是從第一個點開始到最後一個點開始運動的時間,通過

factor - 0.66f / POINT_NUM * index

就可以得到每個圓點的起始時間,再*3將其換算到直線運動的時間上。
將上面的運動組合起來就得到了完整的onDraw方法

    @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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.