一了赌、前言
音樂播放器,我一直是用酷狗的吏夯。不僅僅是因為她的音樂資源此蜈,更主要的是這款App的用戶體驗--各種流暢的滑動,無比絢爛的UI噪生。其中最讓我喜歡的就是她的轉場動畫了裆赵,用起來很順手。
酷狗音樂App流暢的用戶體驗
今天這篇文章先不介紹如何自定義轉場動畫跺嗽。我們主要就來玩一下酷狗音樂的轉場動畫的動畫實現(xiàn)战授。
二、酷狗音樂轉場動畫初探索桨嫁,建立數(shù)學模型
根據(jù)上面的動圖植兰,小伙伴們仔細觀察酷狗音樂是如何將兩個頁面進行轉場的。其實不難發(fā)現(xiàn)A頁面過渡到B頁面璃吧,就是將B頁面旋轉移動過來的楣导。
其移動的方式大致如下圖所示:
酷狗音樂轉場模擬
如上圖,B頁面通過動畫移動到A頁面就是酷狗音樂轉場的一個動畫實現(xiàn)肚逸。很簡單爷辙,通過視圖的transform屬性就能夠實現(xiàn)。
現(xiàn)在面臨的主要問題就是B頁面與A頁面它的一個位置關系是如何的呢朦促?
針對上面的問題膝晾,我們可以從兩個方面來回答:
- A頁面與B頁面有一個角度上的偏移。
這個角度我們可以給個固定值务冕,目測大概25°角血当。 - 在A沿著右下角旋轉25度角后,再沿著垂直邊向上方法平移一定距離禀忆,可到達B頁面臊旭。
這個距離我們也可以給個固定值,大概50point(Point為蘋果的單位箩退,不熟悉的小伙伴請移步iOS繪制1像素線的正確姿勢)
三离熏、計算A,B兩個頁面的角度偏移量與位置偏移量
- A戴涝,B頁面的角度偏移量滋戳。
以蘋果手機左上角為原點坐標钻蔑,即A頁面左上角為原點,B頁面的橫向與縱向邊相對于這個坐標的X軸奸鸯,Y軸的夾角就是A,B頁面的角度偏移量咪笑,即25°。 - A娄涩,B頁面的位置偏移量
我們可以將A窗怒,B頁面的中心點作為參照點。找到兩個頁面中心點在X軸與Y軸的距離就是A蓄拣,B頁面的位置偏移量扬虚。如圖所示:
頁面偏移量
如圖可見,A頁面中心點a與B頁面中心點b的位置偏移量即為:垂直方向上偏移量為線段bc的長度弯蚜,水平方向上偏移量為線段ab的長度
下面我們就來計算線段ab與線段bc的長度
孔轴。
一開始我們也說了A頁面過渡到B頁面剃法,首先是A頁面順時針旋轉25°角碎捺。如圖:
A頁面旋轉25度至B頁面示意圖
如圖可以看到當前的直角△abc。如果B頁面在此基礎上再向上平移50point贷洲,即B頁面中心點b向上平移50point至b'收厨。我們會發(fā)現(xiàn)水平方向的偏移量ac不會改變。垂直方向上偏移量bc在大于50point的時候优构,會減少50point诵叁。
平移后的B頁面
根據(jù)向上平移的多少,b'可能在線段ac的上方或者下方或者acb'三點一線钦椭。
所以我們計算出旋轉且未上移這種狀態(tài)下的ac與bc就能夠計算出旋轉且上移情況下的垂直偏移量與水平偏移量拧额。
假設A頁面長寬分別為2x,2y。 - 首先計算當前斜邊ab
如圖我們做一個輔助線彪腔,連接ad,bd
可知abd為等腰三角形侥锦,并且可以計算出ad與A頁面垂直邊的夾角β=arctan(x/y),那么∠adb=β*2+(25.0/180)*PI德挣。ad=sqrt(x*x+y*y)
恭垦。由此可得ab=2*ad*sin(β/2.0)
。 - 計算∠cab
先計算∠cad=arctan(y/x)
格嗅,再計算∠bad=(PI-∠adb)/2.0番挺。
由此可得∠cab=∠cad-∠bad
。 - 計算橫向偏移量ac
因為△abc為直角三角形屯掖,所以ac=ab*cos(∠cab)
玄柏。 - 計算縱向偏移量bc
bc=ab*sin(∠cab)
四、代碼實現(xiàn)
我們知道A贴铜,B兩個頁面的寬高實際上為手機屏幕的寬高粪摘。這里要注意一點的就是角度的轉換右蒲。
- 角度轉換公式我用的一個宏定義如下:
// 角度轉換
#define angelToRandian(x) ((x)/180.0*M_PI)
- 動畫核心算法
CGFloat x = fromView.frame.size.width * 0.5;
CGFloat y = fromView.frame.size.height * 0.5;
//計算邊長ab函數(shù)
float calculateAB (float x, float y) {
//等腰三角形adb的腰長
float ad = sqrt(pow(x, 2) + pow(y, 2));
//角bda
float bda = atan(x/y)*2+angelToRandian(25);
//角bad
float bad = (M_PI - bda)*0.5;
//邊ab
float ab = (ad * cos(bad))*2;
return ab;
}
//計算角cab函數(shù)
float calculateCAB (float x, float y) {
//角bda
float bda = atan(x/y)*2+angelToRandian(25);
//角bad
float bad = (M_PI - bda)*0.5;
//角cad
float cad = atan(y/x);
//角cab
float cab = cad-bad;
return cab;
}
//計算ac
CGFloat ac = calculateAB(x, y) * cos(calculateCAB(x, y));
//計算bc
CGFloat bc = calculateAB(x, y) * sin(calculateCAB(x, y));
//最終的橫縱向偏移量
CGFloat spacingX = ac;
CGFloat spacingY = 50>bc?50-bc:bc-50;
//設置B頁面的初始位置偏移
toView.transform = CGAffineTransformTranslate(toView.transform, spacingX, spacingY);
//設置B頁面的初始角度偏移
toView.transform = CGAffineTransformRotate(toView.transform, angelToRandian(25));
//開始動畫
[UIView animateWithDuration:3.0 animations:^{
toView.transform = CGAffineTransformIdentity;
}];
動畫效果如下:
仿酷狗音樂轉場動畫
本篇文章作為一個引子,主要是為下一篇如何實現(xiàn)自定義轉場動畫作為鋪墊赶熟。敬請期待瑰妄。喜歡的小伙伴順手給個??,謝謝~