水波动效

应用:一般用于图片装饰,增加层次感。

附上动效图:

实现其实不难,使用遮罩绘制路径即可,这里路径是高中时学过的正弦函数

 y = Asin(wx+b)+c

 - A是指曲线的振幅

 - w好像是相位,决定曲线的周期  2pi/w

 - b,可看做是w(x+b/w),是x的横线偏移量

 - c是y的纵向偏移量

这里附上一张正弦曲线图,搞不懂的同学可以仔细对着图思考一下及各参数的含义

再给大家捋捋

  1.自定义子视图

  2.自定义CAShapeLayer,绘制正弦曲线,赋值为子视图的mask,实现正弦曲线的裁剪效果

  3.绘制多条曲线,相互叠加,实现预期效果

会指曲线的代码如下

- (UIBezierPath *)createSinglePath:(CGFloat)offsetx scale:(int)factor {
    // y = Asin(w(x+b))+c
    /// 振幅A取视图高度 视图宽度刚好为一个周期    横向偏移外部传入,纵向偏移为0
    CGFloat width = CGRectGetWidth(self.frame);
    CGFloat height = CGRectGetHeight(self.frame);
    CGFloat A = height/4;
    CGFloat W = M_PI*2/width;
    CGFloat offy = A*factor;
    
    UIBezierPath *path = [UIBezierPath new];
    // 路径默认剪切i下半部分
    [path moveToPoint:CGPointMake(width, 0)];
    [path addLineToPoint:CGPointMake(0, 0)];
    for (int i = 0; i <= width; i++) {
        CGFloat y = A * sinf(W*(i+offsetx))+offy;
        [path addLineToPoint:CGPointMake(i, y)];
    }
    [path closePath];
    return path;
}

通常是将一个屏幕宽设置为一个周期长,振幅A不要太大,不然不好看,结合CADisplayLink不断偏移x,实现y值上下偏移,空间上给读者一种向左流动的错觉。

{
  CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(refreshWaterWave)];
  link.perferredFramePerSeconds = 30;  // 1秒多少帧,苹果默认是1秒60帧,这里设置为30,意味着1秒刷新2次
  [link addToRunloop:NSRunloop.mainRunloop forMode:NSRunloopCommonModes];
}

- (void)refreshWaterWave {

   static CGFloat offsetX = 0;

   maskLayer.path = [self createSinglePath:offsetX scale:1];

   offsetX += 1;

 }

谈下需要注意的几个细节

1.路径叠加的顺序应该是由上到下,并且底下的波纹应当包含上面的波纹

2.多条波纹之间的偏移速度应当相近,最好能周期性变化,这样使得水波好看

github传送门

原文地址:https://www.cnblogs.com/xiaoerheiwatu/p/9966429.html