先看一下最终效果图:
首先我们可以把如此丝滑的水波纹拆分一下下:
- 一条规律的曲线。
- 曲线匀速向右移动。
- 曲线下方的位置用颜色填充。
于是先来一条曲线吧。
对于需要产生波动如此规律的曲线,我们首先想到的应该就是三角函数了。
例如我们熟悉的正弦曲线:
及其公式:
f(x) = Asin(ωx+φ)+k
而SDK也为我们提供了这个正弦函数:
externdoublesin(double);
于是乎通过一个循环就能轻易地获取到这条曲线了:
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);
}
让它动起来
我们需要在屏幕每次刷新的时候进行一次曲线的绘制,让它不断地刷新。
self.waveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(currentWave)];
而根据上面的正弦函数公式,曲线要向右移,其φ值就需要变小。于是在 currentWave 方法每次调用的时候,offsetX均减去同一个固定值,以实现匀速的运动。
self.offsetX -= self.waveSpeed;
涂个颜色
连个线,形成封闭空间:
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);
再填个色:
self.waveShapeLayer.fillColor =self.waveColor.CGColor;
好了。
至于最后的渐变消失略简单就不说了。有兴趣的直接到文末下载完整代码吧~
多扯两句
这水波纹并不限定在拖动过后才能波动,而是随时想动就动、想停就停。
于是最近我想到了一些新玩法,例如用作刷新等待视图。
更多的玩法就自行发掘吧~
最后
原作者 完整代码GitHub 地址:
Github: https://github.com/WelkinXie/WXWaveView