Android開源:GADownloading - 一個絢麗的下載動效分析與實現

MaritaSoe 8年前發布 | 18K 次閱讀 安卓開發 Android開發 移動開發

閑逛之余,看到一個不錯的downloading動效,這個動效用CJJ的話說難度還好,但本人覺得還比較靈動、帶感、俏皮、有新意,好了話不多說,咱們先來擼一張高清無碼gif圖:

擼完,咱可以將整個動效簡單劃分為以下流程:

  1. BeforeProgress(顯示進度前);
  2. InProgress(顯示進度中);
    3.Failed(失敗動畫);
    4.Done(完成動畫);
    下面咱們一起對以上流程進行分析與實現;

1. BeforeProgress(顯示進度前):

同樣,咱們一起擼一下第一部分高清無碼gif圖:

通過觀察,我們可以將以上動畫分割為以下幾個內容:

1.圓形背景和下載剪頭整體縮放;

2.圓形背景逐步鏤空(縮放到一定階段,內部鏤空圓不斷擴大);

3.圓形背景變為一條直線,并伴隨箭頭些許上移;

4.直線上下震蕩及下載箭頭(Arrow)變承載進度文字的線框形態;

1.1. 圓形背景和下載剪頭整體縮放:

這里面,圓形背景和整體的縮放好說,稍顯麻煩的是下載箭頭,由于后面箭頭還需要形變為承載進度文字的線框,所以丟掉你使用圖片的小想法,咱們一起用path勾一個活潑的小箭頭:

Paste_Image.png

箭頭OK了,圓形背景和整體的縮放就不再細說,只需要canvas.drawCircle()和使用ValueAnimator動態改變canvas縮放比例即可,so easy!

后面箭頭需要形變為承載進度文字的線框,通過觀察,可以看到線框的4個角是圓角。由于使用path勾勒,實現圓角線框大致有以下幾種方案:

1.使用path的quadTo()以二次貝塞爾曲線連接;

2.使用path的arcTo()以圓弧形式連接;

3.使用path中addArc()添加一段圓;

4.使用paint的setPathEffect設置PathEffect為ConnerPathEffect;

本人最終采用第四種方式進行實現;

1.2.圓形背景逐步鏤空(縮放到一定階段,內部鏤空圓不斷擴大):

擼完上圖,我們可看到,圓形背景由實心圓變換至一個圓環,最終消失,此處我們可以想到如下方案:

  1. 直接采用背景的顏色,在里面畫實心圓(需要提前知道背景顏色并且背景只能為純色);
  2. 外面深色的圓直接是圓環,然后通過調整圓的半徑及paint的strokeWidth實現;
    3.直接采用混合模式(Xfermode),圓形背景中混合掉內圓部分;
    第一種方案太挫,帥氣逼人的GAStudio哥肯定不會考慮,本文采用混合模式方案,關鍵代碼如下:

Paste_Image.png

1.3.圓形背景變為一條直線,并伴隨箭頭些許上移:

這個部分相比前面兩步稍顯復雜,需要將圓環如絲般順滑的變換成直線,并隨之上線震蕩,該過程拆解圖如下:

對于這個過程,GAStudio哥采用兩條三階貝塞爾曲線對初期的圓環、中間部分的曲線、最終的直線進行模擬;

為了便于理解,抽象出四個核心狀態,過程圖解如下:

1.完整圓形狀態:

2.延展開來狀態:

3.橫向鋪開狀態:

4.直線狀態:

更新path核心邏輯如下:

Paste_Image.png

Paste_Image.png

Paste_Image.png

整個過程路徑及控制點變化如下:

至此,箭頭上移的效果,只需根據繩子中心點的位置,平移下載箭頭位置即可;

1.4.直線上下震蕩及下載箭頭(Arrow)變承載進度文字的線框形態:

這個過程有以下三點需要考慮:

1.4.1.直線震蕩:

該效果僅需持續上下移動二階貝塞爾曲線的控制點即可,不再多言;

1.4.2.箭頭沿曲線移動:

移動的路線可以采用一個三階貝塞爾曲線進行模擬,再使用PathMeasure獲取過程中的實時位置(x、y),關鍵代碼如下:

Paste_Image.png

1.4.3.移動過程中的下載箭頭形態變換:

咱們用rectWidth、rectHeight分別指代下載箭頭底部的矩形部分的寬高,triWidth、triHeight分別指代Arrow頭部的三角形部分的寬高,angle指代下載箭頭的旋轉角度;

只需用ValueAnimator創建一個過程將以上數值進行如下變換:

rectWidth 到 2rectWidth;

rectHeight 到 1.4rectHeight 再到 rectHeight;

triWidth 到 0.65triWidth;

triHeight 到 0.65*triHeight;

angle 由 0 -> -30 -> 20 -> -10 -> 0度;

OK,到這里,第一部分就可以告一段落,咱們繼續看后面的部分;

2. InProgress(顯示進度中) :

GAStudio哥本次在實現過程中,沒有實現在移動的過程中的線框的搖擺,有興趣的同學可以自己修改實現,剩余部分主要講下拉繩的變動:

2.1. 拉繩的變動:

觀察上圖,可以將拉繩下拉的頂點移動的軌跡近似看成一條折線, 先計算出頂點的位置,再分別繪制左、右兩邊的直線,關鍵代碼如下:

Paste_Image.png

3. Failed(失敗動畫):

擼完以上gif,我們可以把這部分效果分為如下幾點:

1.線框內的文字變為Failed并且晃動;

2.繩子上下抖動;

3.繩子左側的白色部分爆炸消失;

4.線框回到最初位置,變且變為下載箭頭;

5.圓形背景逐漸放大出現;

6.圓形背景和下載箭頭整體縮放;

在這里,我們一起看下爆炸效果的實現,其他部分相對簡單,不再贅述;

關于爆炸效果,我們可以很逼真的模擬,繪制出各式各樣的圓點來模擬,但是由于點的個數多,大小不一,采用該方式費事費力,并且由于效果速度快,轉瞬即逝,我們可以采用一種簡單而效果看起來差不多的方式,就是只畫幾個形狀,然后平鋪到整個繩子;

該處主要使用paint的setPathEffect方法將PathEffect設置為PathDashPathEffect,關鍵代碼如下:

Paste_Image.png

4.Done(完成動畫):

擼完以上gif, 我們可以將該部分概括為以下部分:

  1. 線框繞Y軸旋轉,并由100%變換為done;

    2.線框隨進度條收縮到最中心;

    3.線框在中心點晃動;

    4.線框變換為下載箭頭,圓形背景復出;

    5.圓形背景和下載箭頭整體縮放,伴隨下載箭頭上下晃動;

該部分咱們一起看下第一條的實現,即Canvas里如何實現偽三維變換;

Canvas中只有rotate函數,也就是在二維平面內進行旋轉,不能實現如上的繞Y軸旋轉,類似效果需要借助Camera來實現,關鍵代碼如下:

Paste_Image.png

至此,該效果的核心邏輯咱們已經分析完畢,實現效果如下:

成功部分:

失敗部分:

你以為到這里就結束了嗎?No-No-No,作為一個負責任的開發者,最后咱們加上合理的自定義屬性,以方便使用者自行定義:

 

 本文由用戶 MaritaSoe 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!