iOS 怎么制作出動感的波浪動畫

模擬機Demo浪.gif
表頭浪.gif

實現(xiàn)思路

  1. 定義一個View
  2. 運用CGMutablePathRef 和CAShapeLayer畫出靜態(tài)正弦函數(shù)
  3. 運用幀顯示類CADisplayLink,不斷的改變路徑上的各個點,讓波浪動起來
  4. 回調(diào)每一幀的中點值,可以增加動態(tài)的圓形等自定義視圖

三角函數(shù)

假設 y = Asin(ωx+φ)+ C
A 表示振幅,也就是使用這個變量來調(diào)整波浪的最大的高度
ω 與周期相關,周期 T = 2 x pi / ω ,這個變量用來調(diào)整同寬度內(nèi)顯示的波浪的數(shù)量
φ 表示波浪橫向的偏移,也就是使用這個變量來調(diào)整波浪的流動
C 表示波浪縱向偏移的位置。

正弦函數(shù)伸縮變換
三角函數(shù)平移變換和周期變換

CADisplayLink

一種精確到幀的定時器,其根本是利用刷幀和屏幕頻率一樣來重繪渲染頁面。
注意1:初始CADisplayLink對象,指定target的時候,其屬于單例,會保留其目標對象,而CADisplayLink的目標對象如果恰好保留了計時器本身,就會導致循環(huán)引用。
注意2:frameInterval的值默認為1,真機刷新頻率是每秒60次,所以每一次調(diào)用的“target”函數(shù)的運行的時間大于1/60秒,就會出現(xiàn)嚴重的丟幀現(xiàn)象。frameInterval的值默認為2時,刷新頻率就變?yōu)榱嗣棵?0次。

其創(chuàng)建方式:

    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(wave)];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

NSRunLoop

什么是run loop ,簡單說下:讓線程在有任務的時候忙于工作,而沒任務的時候處于休眠狀態(tài)。
run loop線程開啟的時候便被創(chuàng)建,所以只需要在當前線程獲取即可。

  1. NSDefaultRunLoopMode
    App的默認 Mode,通常主線程是在這個 Mode 下運行的。
  2. UITrackingRunLoopMode
    界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響。
  3. NSRunLoopCommonModes
    公共的mode,即是這個Mode下的事件,可以在其他的Mode下被運行。

CADisplayLink、NSTimer執(zhí)行的小動畫,在拖動scrollView的時候動畫會被暫停,此時就需要設置所加在的run loop 的mode了。

主要代碼:

//創(chuàng)建浪的路徑
CGMutablePathRef wavePath = CGPathCreateMutable();

//創(chuàng)建一個起點
CGPathMoveToPoint(wavePath, NULL, 0, height);

//創(chuàng)建中間點
for (int x = 0; x < width; x++) {
    //主要的實現(xiàn)算法就是y = Asin(ωx+φ) 
    CGFloat y = height  * sinf(self.waveCurve * x * M_PI / 180 + offset * M_PI / 180);
    CGPathAddLineToPoint(wavePath, NULL, x, y);
}

//調(diào)整填充路徑
CGPathAddLineToPoint(wavePath, NULL, width, height);
CGPathAddLineToPoint(wavePath, NULL, 0, height);

//結(jié)束路徑
CGPathCloseSubpath(wavePath);

//用路徑創(chuàng)建浪
waveShapeLayer.path = wavePath;
waveShapeLayer.fillColor = waveWolor.CGColor;

//釋放浪路徑
CGPathRelease(wavePath);

當開始動畫的時候?qū)ADisplayLink對象加到runLoop中

 [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

結(jié)束動畫時注銷掉CADisplayLink對象

 [self.displayLink invalidate];
 self.displayLink = nil;

更多內(nèi)容,請在Demo中查看,F(xiàn)YJWave可導入直接使用~
Demo下載地址

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容