一個(gè)絢麗的loading動(dòng)效分析與實(shí)現(xiàn)!


???? 原文轉(zhuǎn)自極分享?????? 更多詳情及更新查看原文????


前兩天我們這邊的頭兒給我說,有個(gè) gif 動(dòng)效很不錯(cuò),可以考慮用來做項(xiàng)目里的loading,問我能不能實(shí)現(xiàn),看了下效果確實(shí)不錯(cuò),也還比較有新意,復(fù)雜度也不是非常高,所以就花時(shí)間給做了,我們先一起看下原gif圖效果:


從效果上看,我們需要考慮以下幾個(gè)問題:

1.葉子的隨機(jī)產(chǎn)生;

2.葉子隨著一條正余弦曲線移動(dòng);

3.葉子在移動(dòng)的時(shí)候旋轉(zhuǎn),旋轉(zhuǎn)方向隨機(jī),正時(shí)針或逆時(shí)針;

4.葉子遇到進(jìn)度條,似乎是融合進(jìn)入;

5.葉子不能超出最左邊的弧角;

7.葉子飄出時(shí)的角度不是一致,走的曲線的振幅也有差別,否則太有規(guī)律性,缺乏美感;

總的看起來,需要注意和麻煩的地方主要是以上幾點(diǎn),當(dāng)然還有一些細(xì)節(jié)問題,比如最左邊是圓弧等等;

那接下來我們將效果進(jìn)行分解,然后逐個(gè)擊破:

整個(gè)效果來說,我們需要的圖主要是飛動(dòng)的小葉子和右邊旋轉(zhuǎn)的風(fēng)扇,其他的部分都可以用色值進(jìn)行繪制,當(dāng)然我們?yōu)榱朔奖?,就連底部框一起切了;

先從gif 圖里把飛動(dòng)的小葉子和右邊旋轉(zhuǎn)的風(fēng)扇、底部框摳出來,小葉子圖如下:


我們需要處理的主要有兩個(gè)部分:

1. 隨著進(jìn)度往前繪制的進(jìn)度條;

2. 不斷飛出來的小葉片;

我們先處理第一部分 - 隨著進(jìn)度往前繪制的進(jìn)度條:

進(jìn)度條的位置根據(jù)外層傳入的 progress 進(jìn)行計(jì)算,可以分為圖中 1、2、3 三個(gè)階段:


1. 當(dāng)progress 較小,算出的當(dāng)前距離還在弧形以內(nèi)時(shí),需要繪制如圖所示 1 區(qū)域的弧形,其余部分用白色填充;

2. 當(dāng) progress 算出的距離到2時(shí),需要繪制棕色半圓弧形,其余部分用白色矩形填充;

3. 當(dāng) progress 算出的距離到3 時(shí),需要繪制棕色半圓弧形,棕色矩形,白色矩形;

4. 當(dāng) progress 算出的距離到頭時(shí),需要繪制棕色半圓弧形,棕色矩形;(可以合并到3中)

// mProgressWidth為進(jìn)度條的寬度,根據(jù)當(dāng)前進(jìn)度算出進(jìn)度條的位置

mCurrentProgressPosition = mProgressWidth * mProgress / TOTAL_PROGRESS;

// 即當(dāng)前位置在圖中所示1范圍內(nèi)

if (mCurrentProgressPosition < mArcRadius) {

Log.i(TAG, "mProgress = " + mProgress + "---mCurrentProgressPosition = "

+ mCurrentProgressPosition

+ "--mArcProgressWidth" + mArcRadius);

// 1.繪制白色ARC,繪制orange ARC

// 2.繪制白色矩形

// 1.繪制白色ARC

canvas.drawArc(mArcRectF, 90, 180, false, mWhitePaint);

// 2.繪制白色矩形

mWhiteRectF.left = mArcRightLocation;

canvas.drawRect(mWhiteRectF, mWhitePaint);

// 3.繪制棕色 ARC

// 單邊角度

int angle = (int) Math.toDegrees(Math.acos((mArcRadius - mCurrentProgressPosition)

/ (float) mArcRadius));

// 起始的位置

int startAngle = 180 - angle;

// 掃過的角度

int sweepAngle = 2 * angle;

Log.i(TAG, "startAngle = " + startAngle);

canvas.drawArc(mArcRectF, startAngle, sweepAngle, false, mOrangePaint);

} else {

Log.i(TAG, "mProgress = " + mProgress + "---transfer-----mCurrentProgressPosition = "

+ mCurrentProgressPosition

+ "--mArcProgressWidth" + mArcRadius);

// 1.繪制white RECT

// 2.繪制Orange ARC

// 3.繪制orange RECT

// 1.繪制white RECT

mWhiteRectF.left = mCurrentProgressPosition;

canvas.drawRect(mWhiteRectF, mWhitePaint);

// 2.繪制Orange ARC

canvas.drawArc(mArcRectF, 90, 180, false, mOrangePaint);

// 3.繪制orange RECT

mOrangeRectF.left = mArcRightLocation;

mOrangeRectF.right = mCurrentProgressPosition;

canvas.drawRect(mOrangeRectF, mOrangePaint);

}

代碼部分

最終效果如下,本來錄了20+s,但是PS只能轉(zhuǎn)5s,所以有興趣的大家自己運(yùn)行的玩吧:


源代碼下載??



???? 原文轉(zhuǎn)自極分享???? 更多詳情及更新查看原文????

感謝極分享的 janking? ? ? ? 感謝原文作者? Ajian_studio


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容