???? 原文轉(zhuǎn)自極分享?????? 更多詳情及更新查看原文????
前兩天我們這邊的頭兒給我說,有個 gif 動效很不錯塔鳍,可以考慮用來做項目里的loading伯铣,問我能不能實現(xiàn),看了下效果確實不錯轮纫,也還比較有新意腔寡,復(fù)雜度也不是非常高,所以就花時間給做了蜡感,我們先一起看下原gif圖效果:
從效果上看蹬蚁,我們需要考慮以下幾個問題:
1.葉子的隨機產(chǎn)生;
2.葉子隨著一條正余弦曲線移動郑兴;
3.葉子在移動的時候旋轉(zhuǎn),旋轉(zhuǎn)方向隨機贝乎,正時針或逆時針情连;
4.葉子遇到進度條,似乎是融合進入览效;
5.葉子不能超出最左邊的弧角却舀;
7.葉子飄出時的角度不是一致,走的曲線的振幅也有差別锤灿,否則太有規(guī)律性挽拔,缺乏美感;
總的看起來但校,需要注意和麻煩的地方主要是以上幾點螃诅,當(dāng)然還有一些細節(jié)問題,比如最左邊是圓弧等等状囱;
那接下來我們將效果進行分解术裸,然后逐個擊破:
整個效果來說,我們需要的圖主要是飛動的小葉子和右邊旋轉(zhuǎn)的風(fēng)扇亭枷,其他的部分都可以用色值進行繪制袭艺,當(dāng)然我們?yōu)榱朔奖悖瓦B底部框一起切了叨粘;
先從gif 圖里把飛動的小葉子和右邊旋轉(zhuǎn)的風(fēng)扇猾编、底部框摳出來瘤睹,小葉子圖如下:
我們需要處理的主要有兩個部分:
1. 隨著進度往前繪制的進度條;
2. 不斷飛出來的小葉片答倡;
我們先處理第一部分 - 隨著進度往前繪制的進度條:
進度條的位置根據(jù)外層傳入的 progress 進行計算轰传,可以分為圖中 1、2苇羡、3 三個階段:
1. 當(dāng)progress 較小绸吸,算出的當(dāng)前距離還在弧形以內(nèi)時,需要繪制如圖所示 1 區(qū)域的弧形设江,其余部分用白色填充锦茁;
2. 當(dāng) progress 算出的距離到2時,需要繪制棕色半圓弧形叉存,其余部分用白色矩形填充码俩;
3. 當(dāng) progress 算出的距離到3 時,需要繪制棕色半圓弧形歼捏,棕色矩形稿存,白色矩形;
4. 當(dāng) progress 算出的距離到頭時瞳秽,需要繪制棕色半圓弧形瓣履,棕色矩形;(可以合并到3中)
// mProgressWidth為進度條的寬度练俐,根據(jù)當(dāng)前進度算出進度條的位置
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燕锥,所以有興趣的大家自己運行的玩吧:
源代碼下載??
???? 原文轉(zhuǎn)自極分享???? 更多詳情及更新查看原文????
感謝極分享的 janking? ? ? ? 感謝原文作者? Ajian_studio