為視圖添加絲滑的水波紋

由于前段時(shí)間發(fā)現(xiàn)自己在Github上的這份代碼被簡(jiǎn)書上某用戶直接拷貝來發(fā)表了,而又并沒有注明代碼出處,于是決定還是自己著手寫一篇好了。

先看一下最終效果圖:

首先我們可以把如此絲滑的水波紋拆分一下下:

  • 一條規(guī)律的曲線。
  • 曲線勻速向右移動(dòng)。
  • 曲線下方的位置用顏色填充。

于是先來一條曲線吧。

對(duì)于需要產(chǎn)生波動(dòng)如此規(guī)律的曲線,我們首先想到的應(yīng)該就是三角函數(shù)了。

例如我們熟悉的正弦曲線:

及其公式:

f(x) = Asin(ωx+φ)+k

而SDK也為我們提供了這個(gè)正弦函數(shù):

extern double sin(double);

于是乎通過一個(gè)循環(huán)就能輕易地獲取到這條曲線了:

CGFloat y = 0.f;
for (CGFloat x = 0.f; x <= CGRectGetWidth(self.frame) ; x++) {
    y = height * sin(self.angularSpeed * x + self.offsetX);
    CGPathAddLineToPoint(path, NULL, x, y);
}

讓它動(dòng)起來

我們需要在屏幕每次刷新的時(shí)候進(jìn)行一次曲線的繪制,讓它不斷地刷新。

self.waveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(currentWave)];

而根據(jù)上面的正弦函數(shù)公式,曲線要向右移,其φ值就需要變小。于是在 currentWave 方法每次調(diào)用的時(shí)候,offsetX均減去同一個(gè)固定值,以實(shí)現(xiàn)勻速的運(yùn)動(dòng)。

self.offsetX -= self.waveSpeed;

涂個(gè)顏色

連個(gè)線,形成封閉空間:

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 0, height / 2);

CGFloat y = 0.f;
for (CGFloat x = 0.f; x <= CGRectGetWidth(self.frame) ; x++) {
    y = height * sin(self.angularSpeed * x + self.offsetX);
    CGPathAddLineToPoint(path, NULL, x, y);
}
CGPathAddLineToPoint(path, NULL, width, height);
CGPathAddLineToPoint(path, NULL, 0, height);
CGPathCloseSubpath(path);

再填個(gè)色:

self.waveShapeLayer.fillColor = self.waveColor.CGColor;

好了。

至于最后的漸變消失略簡(jiǎn)單就不說了。有興趣的直接到文末下載完整代碼吧~

多扯兩句

這水波紋并不限定在拖動(dòng)過后才能波動(dòng),而是隨時(shí)想動(dòng)就動(dòng)、想停就停。

于是最近我想到了一些新玩法,例如用作刷新等待視圖。

更多的玩法就自行發(fā)掘吧~

最后

完整代碼呈上:

Github: WXWaveView

其使用方法在該頁(yè)面中會(huì)有介紹。

喜歡的歡迎給個(gè)star~玩得開心哈。

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

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

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