乾貨系列之手把手教你使用Core animation 做動畫

發表於2016-03-25

原始碼下載:原始碼

最近在技術群裡,有人發了一張帶有動畫效果的圖片。覺得很有意思,便動手實現了一下。在這篇文章中你將會學到Core Animation顯式動畫中的關鍵幀動畫、組合動畫、CABasicAnimation動畫。先上一張原圖的動畫效果。

點選此檢視原圖動畫效果

本文要實現的效果圖如下:

 
實現的效果圖.gif

把原動畫gif動畫在mac上使用圖片瀏覽模式開啟,我們可以看到動畫每一幀的顯示。從每一幀上的展示過程,可以把整體的動畫進行拆分成兩大部分。

第一部分(Part1)從初始狀態變成取消狀態(圖片上是由橫實線變成上線橫線交叉的圓)。
第二部分(Part2)從取消狀態變回初始狀態。

下面我們先詳細分析Part1是怎麼實現的。根據動畫圖,把Part1再細分成三步。

Step1 : 中間橫實線的由右向左的運動效果。這其實是一個組合動畫。是先向左偏移的同時橫線變短。先看一下實現的動態效果。

 
step1 Animation.gif

■ 向左偏移—使用基本動畫中animationWithKeyPath鍵值對的方式來改變動畫的值。我們這裡使用position.x,同樣可以使用transform.translation.x來平移。

■ 改變橫線的大小—使用經典的strokeStartstrokeEnd。其實上橫線長度的變化的由strokeStartstrokeEnd之間的值來共同來決定。改變strokeEnd的值由1.0到0.4,不改變strokeStart的值。橫線的長度會從右側方向由1.0倍長度減少到0.4倍長度。參見示意圖的紅色區域。

 
stroke示意圖.png

Step2 : 由左向右的動畫–向右偏移同時橫線長度變長。看一下Step2要實現的動畫效果。其思路和Step1是一樣的。

 
step2 Animation.gif

Step3: 圓弧的動畫效果和上下兩個橫實線的動畫效果。

  1. 畫圓弧,首先想到是使用UIBezierPath。畫個示意圖來分析動畫路徑。示意圖如下:
 
step3 示意圖.jpg

整個path路徑是由三部分組成,ABC曲線CD圓弧DD′圓
使用UIBezierPath的方法

把三部分路徑關聯起來。詳細講解思路。

ABC曲線就是貝塞爾曲線,可以根據A、B、C三點的位置使用方法

二次貝塞爾曲線示意圖如下:

 
二次貝塞爾曲線.png

其中control point 點是從曲線上取 start point和end point 切點相交匯的所得到的交點。如下圖:

 
control point .png

首先C點取圓上的一點,-30°。那麼,

C點座標為:

A點座標為:

control point 為E點:

CD圓弧的路徑使用此方法確定

關於弧度問題,UIBezierPath的官方文件中的這張圖:

 
弧度.jpg

StartAngle 弧度即C點弧度,EndAngel弧度即D點弧度。

DD′圓的路徑和上面2一樣的方法確定。

StartAngle 弧度即D點弧度,EndAngel弧度即D′點弧度。

下面部分程式碼是所有path路徑。

Path路徑有了,接著實現動畫效果。
圓弧的長度逐漸變長。我們還是使用經典的strokeStartstrokeEnd。但是圓弧是如何變長的呢?

(1) 初始圓弧有一段長度。
(2) 在原始長度的基礎上逐漸變長,逐漸遠離A點,同時要在D點停止。
(3) 長度逐漸變長,最終要在D與D′點交匯。

我們分別解決這個三個問題。

第一個問題,strokeEnd - strokeStart > 0這樣能保證有一段圓弧。

第二個問題,逐漸變長,意味著strokeEnd值不斷變大。遠離A點意味著strokeStart的值不斷變大。在D點停止,說明了strokeStart有上限值。

第三個問題,意味著strokeEnd值不斷變大,最終值為1.0。

這三個問題說明了一個問題,strokeEndstrokeStart是一組變化的資料。

那麼core animation 中可以控制一組值的動畫是關鍵幀動畫(CAKeyframeAnimation)。

為了更準確的給出strokeEndstrokeStart值,我們使用長度比來確定。

假設我們初始的長度就是曲線ABC的長度。但是貝塞爾曲線長度怎麼計算?使用下面方法:

計算貝塞爾曲線所在的比例為:

初始的strokeStart = 0strokeEnd = orignPercent
最終的stokeStart = ?

實現動畫的程式碼為

效果圖為:

 
step3-1 Animation.gif

2.上下橫線的動畫效果。

此動畫效果,需要使用transform.rotation.z轉動角度。

上橫線轉動的角度順序為 0 -> 10° -> (-55°) -> (-45°)
這是一組資料,使用關鍵幀處理動畫。

下橫線轉動的角度順序為0 -> (-10°) -> (55°) -> (45°)

你認為這麼就結束了? 最終結束的動畫如下:

 
step3-2 finished Animation.jpg

發現相交的直線沒有居中,而是靠左顯示。

向左平移,使用transform.translation.x

即旋轉角度又發生偏移量,使用組合動畫。

上橫線組合動畫

下橫線組合動畫

Part1到此結束。最終效果圖

 
Part1 animation.gif

Part2的思路和Part1思路是一樣的。你可以參考程式碼自己思考一下。核心程式碼

最終效果圖:

 
finished animation.gif

本篇文章講解結束!

程式碼點此連結下載:https://github.com/WZF-Fei/ZFChangeAnimation

相關文章