一個絢麗的loading動效分析與實現!
尊重原創,歡迎轉載,轉載請註明: FROM GA_studio http://blog.csdn.net/tianjian4592
前兩天我們這邊的頭兒給我說,有個 gif 動效很不錯,可以考慮用來做專案裡的loading,問我能不能實現,看了下效果確實不錯,也還比較有新意,複雜度也不是非常高,所以就花時間給做了,我們先一起看下原gif圖效果:
從效果上看,我們需要考慮以下幾個問題:
1.葉子的隨機產生;
2.葉子隨著一條正餘弦曲線移動;
3.葉子在移動的時候旋轉,旋轉方向隨機,正時針或逆時針;
4.葉子遇到進度條,似乎是融合進入;
5.葉子不能超出最左邊的弧角;
7.葉子飄出時的角度不是一致,走的曲線的振幅也有差別,否則太有規律性,缺乏美感;
總的看起來,需要注意和麻煩的地方主要是以上幾點,當然還有一些細節問題,比如最左邊是圓弧等等;
那接下來我們將效果進行分解,然後逐個擊破:
整個效果來說,我們需要的圖主要是飛動的小葉子和右邊旋轉的風扇,其他的部分都可以用色值進行繪製,當然我們為了方便,就連底部框一起切了;
先從gif 圖裡把飛動的小葉子和右邊旋轉的風扇、底部框摳出來,小葉子圖如下:
我們需要處理的主要有兩個部分:
1. 隨著進度往前繪製的進度條;
2. 不斷飛出來的小葉片;
我們先處理第一部分 - 隨著進度往前繪製的進度條:
進度條的位置根據外層傳入的 progress 進行計算,可以分為圖中 1、2、3 三個階段:
1. 當progress 較小,算出的當前距離還在弧形以內時,需要繪製如圖所示 1 區域的弧形,其餘部分用白色填充;
2. 當 progress 算出的距離到2時,需要繪製棕色半圓弧形,其餘部分用白色矩形填充;
3. 當 progress 算出的距離到3 時,需要繪製棕色半圓弧形,棕色矩形,白色矩形;
4. 當 progress 算出的距離到頭時,需要繪製棕色半圓弧形,棕色矩形;(可以合併到3中)
首先根據進度條的寬度和當前進度、總進度算出當前的位置:
[html] view plain copy
- //mProgressWidth為進度條的寬度,根據當前進度算出進度條的位置
- mCurrentProgressPosition = mProgressWidth * mProgress / TOTAL_PROGRESS;
[html] view plain copy
- // 單邊角度
- int angle = (int) Math.toDegrees(Math.acos((mArcRadius - mCurrentProgressPosition)/ (float) mArcRadius));
Math.toDegrees() - 弧度轉化為角度,Math.toRadians 角度轉化為弧度
所以圓弧的起始點為:
[html] view plain copy
- int startAngle = 180 - angle;
[html] view plain copy
- 2 * angle
[html] view plain copy
- // mProgressWidth為進度條的寬度,根據當前進度算出進度條的位置
- mCurrentProgressPosition = mProgressWidth * mProgress / TOTAL_PROGRESS;
- // 即當前位置在圖中所示1範圍內
- 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);
- }
接下來再來看葉子部分:
首先根據效果情況基本確定出 曲線函式,標準函式方程為:y = A(wx+Q)+h,其中w影響週期,A影響振幅 ,週期T= 2 * Math.PI/w;
根據效果可以看出,週期大致為總進度長度,所以確定w=(float) ((float) 2 * Math.PI /mProgressWidth);
仔細觀察效果,我們可以發現,葉子飄動的過程中振幅不是完全一致的,產生一種錯落的效果,既然如此,我們給葉子定義一個Type,根據Type 確定不同的振幅;
我們建立一個葉子物件:
[html] view plain copy
- private class Leaf {
- // 在繪製部分的位置
- float x, y;
- // 控制葉子飄動的幅度
- StartType type;
- // 旋轉角度
- int rotateAngle;
- // 旋轉方向--0代表順時針,1代表逆時針
- int rotateDirection;
- // 起始時間(ms)
- long startTime;
- }
型別採用列舉進行定義,其實就是用來區分不同的振幅:
[html] view plain copy
- private enum StartType {
- LITTLE, MIDDLE, BIG
- }
建立一個LeafFactory類用於建立一個或多個葉子資訊:
[html] view plain copy
- private class LeafFactory {
- private static final int MAX_LEAFS = 6;
- Random random = new Random();
- // 生成一個葉子資訊
- public Leaf generateLeaf() {
- Leaf leaf = new Leaf();
- int randomType = random.nextInt(3);
- // 隨時型別- 隨機振幅
-
相關推薦
一個絢麗的loading動效分析與實現!
尊重原創,歡迎轉載,轉載請註明: FROM GA_studio http://blog.csdn.net/tianjian4592
Android 漂浮類動效的分析與實現!
注:因部分原因,本篇主要講解動效分析的思路,不提供原始碼下載,請見諒 ... ... 上一篇只講了Canvas中的drawBitmap方法,並且還說的這個方法好像很膩害、能做出很多牛逼效果的樣子,
C++ 單鏈表基本操作分析與實現 連結串列 連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結
連結串列 連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。 相比於線性表
跳躍表的分析與實現
insert text 站點 avi 初始 解析 鏈接 solid water ----《大規模分布式存儲系統:原理解析與架構實戰》讀書筆記 在了解了 Bitcask存儲模型後,又開始研究LSM樹存儲引擎。LSM在實現的過程中使用了一個非常有意思的數
Java排序算法分析與實現:快排、冒泡排序、選擇排序、插入排序、歸並排序(二)
第一個元素 spa insert 循環 冒泡排序 author 高級算法 ins -s 一、概述: 上篇博客介紹了常見簡單算法:冒泡排序、選擇排序和插入排序。本文介紹高級排序算法:快速排序和歸並排序。在開始介紹算法之前,首先介紹高級算法所需要的基礎知識:劃分、遞歸,並順
信息摘要算法之五:HMAC算法分析與實現
UC str 就是 n) auth 如果 輸出 返回 digest MAC(Message Authentication Code,消息認證碼算法)是含有密鑰散列函數算法,兼容了MD和SHA算法的特性,並在此基礎上加上了密鑰。因此MAC算法也經常被稱作HMAC算法。 1、H
信息摘要算法之六:HKDF算法分析與實現
.com 方式 ems class 偽隨機 不一定 urn 如果 生成 HKDF是一種特定的鍵衍生函數(KDF),即初始鍵控材料的功能,KDF從其中派生出一個或多個密碼強大的密鑰。在此我們想要描述的是基於HMAC的HKDF。 1、HKDF概述 密鑰派生函數(KDF)是密碼系
線程上下文類加載器分析與實現
背景 需求 clas htm ima ref 好的 技術分享 ren 在上一次【https://www.cnblogs.com/webor2006/p/9246850.html】分析源碼中發現有兩處設置線程上下文類加載器的代碼,如下: 因為它是非常重要的東東,所以
數據壓縮算法---LZ77算法 的分析與實現
發現 如何 存儲 sse 而已 以及 turn 集合 alt LZ77簡介 Ziv和Lempel於1977年發表題為“順序數據壓縮的一個通用算法(A Universal Algorithm for Sequential Data Compression )”的論文,論文中描
Android-貪吃蛇小遊戲-分析與實現-Kotlin語言描述
otl bject vid oid 小遊戲 同時 們的 http 畫布 Android-貪吃蛇小遊戲-分析與實現-Kotlin語言描述 Overview 本章的主要的內容是貪吃蛇小遊戲的分析和實現,關於實現的具體代碼可以在,文章底部的github的鏈接中找到。 整個遊戲通過
(轉)從信息隱藏的一個需求看C++接口與實現的分離
要求 member 不可 所有 stack log virtual overflow int 原文地址https://blog.csdn.net/tonywearme/article/details/6926649 讓我們從stackoverflow上一個同學的問題來開始。
手撕MyBatis底層原始碼分析與實現
MyBatis Hiberante 簡介 什麼是 MyBatis ? MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單
十四 第三章再續 快速選擇SELECT演算法的深入分析與實現
十四、亦第三章再續:快速選擇SELECT演算法的深入分析與實現前言 經典演算法研究系列已經寫了十三個演算法,共計22篇文章(詳情,見這:十三個經典演算法研究與總結、目錄+索引),我很怕我自己不再把這個算法系列給繼續寫下去
HTTP Live Streaming直播(iOS直播)技術分析與實現
不經意間發現,大半年沒寫部落格了,自覺汗顏。實則2012後半年(2018年注:這是我以前寫的文章,不要奇怪時間了),家中的事一樣接著一樣發生,實在是沒有時間。快過年了,總算忙裡偷閒,把最近的一些技術成果,總結成了文章,與大家分享。 前些日子,也是專案需要,花了一
Linux I2C驅動分析與實現--例子
通過上篇《Linux I2C驅動分析與實現(二)》,我們對Linux子系統已經不陌生,那麼如何實現I2C驅動呢? 編寫客戶驅動的方法 在核心中有兩種方式的i2c客戶驅動的編寫方法,一種叫legacy傳統方式,另一種是newstyle方式. 前 一種legacy是一種舊式的方法,在2.
智慧指標的分析與實現
一,為什麼要用智慧指標 在編寫c++程式的時候,讓我們最頭痛的問題就是記憶體洩露,也就是說 int* pt = new int; delete pt; 必須保證new和delete必須成對出現。作為程式猿,可以像使用普通變數一樣來使用指標,這個指標可以在恰當的時候被自動釋放,智慧指標
DB Scan演算法的分析與實現
根據上面第二個資料集的簇的形狀比較怪異,分簇結果應該是連起來的屬於一個簇,但是k-means結果分出來很不如人意,所以這裡介紹一種新的聚類方法,此方法不同於上一個基於劃分的方法,基於劃分主要發現圓形或者球形簇;為了發現任意形狀的簇,用一個基於密度的聚類方法,這類方法將簇看做是資料空間中被低
七種排序演算法的簡單分析與實現
{ int nFirst = nLow; int nMid = (nLow + nHigh) /2; int nSecond = nMid +1; int* p = (int*)malloc(sizeof(int) * (nHigh - nLow +1)); int nIndex
c與c++相互呼叫機制分析與實現
c++通常被稱為Better c,多數是因為c++程式可以很簡單的呼叫c函式,語法上基本實現相容。最常用的呼叫方式就是c++模組呼叫c實現的dll匯出函式,很簡單的用法,使用extern "C"將c標頭檔案或者函式修飾下。 本文主要涉及到在c模組中如何呼叫c++函式,或者換個名字,extern
iOS開發之蝦米音樂頻道選擇切換效果分析與實現
今天部落格的內容比較簡單,就是看一下蝦米音樂首頁中頻道選擇的一個動畫效果的實現。之前用mask寫過另外一種Tab切換的一種效果,網易雲音樂裡邊的一種Tab切換效果,詳情請移步於""。,下面會對效果進行分析,並且根據自己的理解去實現一個類似的頻道選擇切換效果。程式碼會在Github上進行分享,Demo實現時依然