iOS实现水波动画
前言
iOS下实现水波动画,动画曲线使用的是正弦型函数解析式
。
效果图如下(图在最后有点卡顿的感觉,是因为gif重新开始播放了)
PS:gif图中下面的
Water
,在水波动画的基础上,使用遮罩实现了Water
字体的蓝白颜色交替
正弦函数
正弦函数是高中学过的知识,这里不再做详细介绍,具体可以查看百科。
我们主要使用到的是正弦函数的几个性质:
1 | 正弦型函数解析式:y = a * sin(ωx+φ)+ h |
动画解析
我们先来看上面方形的水波,主要就是利用正弦函数
绘制出路径即可,如图:
我们知道,虽然我们肉眼看到的曲线是连续的,但是实际将曲线放大到一定程度,看到的是栅格的像素点。
所以我们只要计算出上图中的4个蓝色点
,以及弧线上的所有点,再将之全部连成线,即可形成我们需要的水波形状。
我们从左上角的点开始,依次计算弧线上的点,以及之后的3个蓝色点
即可,这里我们使用UIBezierPath
来进行绘制(当然也可以使用CGMutablePathRef
等),关键代码如下:
1 | UIBezierPath *path = [UIBezierPath bezierPath]; |
这里对使用到的正弦函数
相关参数进行一下说明:
回顾一下正弦函数解析式:
1 | y = a * sin(ωx+φ)+ h |
各参数值说明:
下面的
waveWidth
为容器的宽度
1 | `a`:峰值,值越大,峰越陡,我们可以通过调节该值,来实现水波波动的视觉效果; |
经过多次调试后,我使用了以下参数:
1 | CGFloat y = 2 * a * sin(2.5 * M_PI / waveWidth * x + offset * M_PI / waveWidth) + leftUpPointY; |
以上就可以绘制出一段水波曲线了,不过还只是静态的,我们需要让水波连续地波动,就需要重复地进行绘制,并且在绘制过程中通过改变a
值/φ
值,来形成高低错落有致的视觉效果。
最开始我使用的是CADisplayLink
来进行重复绘制,但是发现60帧/秒
的频率,即1/60 = 0.017秒
就重新进行一次绘制,速度有点快,导致CPU会上升得比较多。所以现在改用NSTimer
,每0.05秒
才进行一次绘制。
其中在NSTimer
的每次回调里改变a
值/φ
值后再进行新的绘制:
1 | a = (toAdd ? a + 0.01 : a - 0.01); |
蓝白颜色交替
之前无意中看到网上有人弄了水波动画(详见这里),就想着自己研究实现一下。
把水波的绘制动画研究出来后,发现那个demo
里还有个颜色交替
的效果,刚好以前弄过类似的,看了下源码,实现思路基本差不多:
使用2张图片,如图:
使用2个UIImageView
分别放置2张图片,白色底
的放下面,蓝色底
的放上面,然后再在蓝色底
的upImageView.layer
上加一层mask
遮罩。
遮罩的路径也就是上面绘制水波的路径,只是不将路径绘制好后的CAShapeLayer
加到容器的layer
上去,而是设置为upImageView.layer
的mask
:
1 | self.upImgView.layer.mask = self.waveLayer; |
总结
这里主要使用到的是正弦函数
,正好复习了一下,能够应用到实际开发中去是挺有成就感的一件事。
这个动画的难点主要是弧线上的点的计算,不过只要多花点时间就可以得到一个满意的结果了。
代码已上传至github
,需要可以去查看:水波动画源码
2016-08-04 01:42
Aevit
华师
Author: Arvit
Link: https://arvit.xyz/2016/08/04/github-wave-animation/
License: 知识共享署名-非商业性使用 4.0 国际许可协议