波浪效果

在工程中碰到了需要实现波浪动画。只知道是使用正弦函数余弦函数CADisplayLink来实现。

正弦,余弦函数就不多说了  y = Asin(ωx+φ) + k,不同的参数控制正弦曲线的显示效果。

A——振幅,当物体作轨迹符合正弦曲线的直线往复运动时,其值为行程的1/2。

(ωx+φ)——相位,反映变量y所处的状态。

φ——初相,x=0时的相位;反映在坐标系上则为图像的左右移动。

k——偏距,反映在坐标系上则为图像的上移或下移。

ω——角速度, 控制正弦周期(单位角度内震动的次数)。


CADisplayLink 这个对象和 NSTimer 类似,是一个定时触发指定方法对象,同样也需要加入一个 NSRunLoop 内才能持续执行。

CADisplayLink 执行的周期和 NSTimer 又不相同,NSTimer 可以自定义周期,而 CADisplayLink 是根据屏幕刷新周期为周期(1/60秒)

如下图:

波浪效果_第1张图片
波浪

一、绘制静态曲线

波浪效果其实说白了就是两条移动的正余弦曲线,而绘制曲线则需要正余弦函数。

首先来看下不会动的波浪。

波浪效果_第2张图片
其实就是两条曲线。

曲线可以看做一段段很短的直线连接起来绘制的。

绘制直线则可以使用 Core GraphicsUIBezierPath CAShapeLayer 来绘制。

- (CAShapeLayer *)firstWavelayer {

           if (!_firstWavelayer) {

                 _firstWavelayer = [CAShapeLayer layer];

                _firstWavelayer.fillColor = [UIColor yellowColor].CGColor; // 填充色

                _firstWavelayer.strokeColor = [UIColor blueColor].CGColor; // 线的颜色

           }

          return _firstWavelayer;

} // 懒加载一个 CAShapeLayer

绘制一条正弦曲线

- (void)drawFirstWave {

         _waveMoveFirst = _waveMoveFirst + 0.2;

        [self.layer addSublayer:self.firstWavelayer];

        CGMutablePathRef ref = CGPathCreateMutable();

        CGPathMoveToPoint(ref, nil, 0, self.frame.size.height);

// 根据 y = Asin(ωx+φ) + k 的 x 变化来延展曲线,通过 φ 来移动曲线

        for (NSInteger i = 0; i <= self.frame.size.width ; i++) {

             double y = 10 * sin(0.1 * i + _waveMoveFirst) + 10;

             CGPathAddLineToPoint(ref, nil, i, y);

         }

//填充底部颜色

        CGPathAddLineToPoint(ref, nil, self.bounds.size.width,         self.bounds.size.height);

        CGPathAddLineToPoint(ref, nil, 0, self.bounds.size.height);

        CGPathCloseSubpath(ref);

        self.firstWavelayer.path = ref;

        CGPathRelease(ref);

}


通过以上代码则绘制一条静止的曲线。

第二条曲线和第一条绘制代码相同。


二、曲线动起来

要想曲线动起来根据 y = Asin(ωx+φ) + k,通过 φ 值的不断变化来实现移动。

创建一个:

_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(moveWave)];

NSRunLoop *runloop =  [NSRunLoop currentRunLoop];

[_displayLink addToRunLoop:runloop forMode:NSRunLoopCommonModes];

- (void)moveWave {

       [self drawFirstWave];

}

通过类型定时器 CADisplayLink 对象来 1/60 s 来执行一次 drawFirstWave 方法来实现 _waveMoveFirst 的值不断变化,从而达到曲线运动的效果。

波浪效果_第3张图片



你可能感兴趣的:(波浪效果)