???? 原文轉(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