IOS实现水波纹

发布时间 2023-04-05 14:11:42作者: R1cardo

IOS实现水波纹

需要实现一个水波纹效果

RPReplay_Final1679274469

其实就是画两个正弦函数或者余弦函数的layer在view上面,根据屏幕刷新率来重绘,更新其左右偏移量来让其看起来是在左右移动

具体实现

  1. 定义两个layer,用不同的颜色填充
    lazy var frontLayer: CAShapeLayer = {
        let tempV = CAShapeLayer()
        tempV.fillColor = frontColor.cgColor
        return tempV
    }()
    
    lazy var backLayer: CAShapeLayer = {
        let tempV = CAShapeLayer()
        tempV.fillColor = backColor.cgColor
        return tempV
    }()
  1. 通过CADisplayLink来保持和屏幕相同的刷新率
    lazy var displayLink: CADisplayLink = {
        let tempV = CADisplayLink(target: self, selector: #selector(updateWave))
        return tempV
    }()

    displayLink.add(to: RunLoop.main, forMode: .common)

CADisplayLink其实也就是一个和屏幕刷新频率相同的Timer,在每次屏幕刷新的时候就会调用传进去的Selector,初始化完成后需要通过.add方法加入到Runloop中

不用时销毁,调用invalidate()方法

displayLink.invalidate()

  1. 更新layer

在更新layer的updateWave方法中将我们的线条画出来

复习一下正弦函数公式

y=Asin(ωx+φ)+ b

其中

  • A: 曲线的振幅,曲线最高位和最低位的距离
  • ω: 曲线的角速度,用于控制周期大小,越大宽越小
  • φ: 曲线的初相,决定X轴的偏移量
  • b: 曲线的偏距,决定Y轴的偏移量

在代码中

    /// 速度
    var speed: CGFloat = 0.01
    
    /// 振幅,曲线最高位和最低位的距离
    var amplitude: CGFloat = 10.0
    
    /// 初相,曲线左右偏移量
    var offsetX: CGFloat = 0.0
    
    /// 角速度,用于控制周期大小,单位x中起伏的个数
    var angularVelocity: CGFloat = 1.0
    
    /// Y轴偏移量,偏距,曲线上下偏移量
    var offsetY: CGFloat = 0.0

以前面这个layer为例

        // 创建一个路径
        let firstPath = CGMutablePath()
        var firstY = bounds.size.width / 2
        firstPath.move(to: CGPoint(x: 0, y: firstY))
        for x in 0...Int(bounds.size.width) {
            firstY = amplitude * sin(angularVelocity * CGFloat(x) + offsetX) + offsetY
            firstPath.addLine(to: CGPoint(x: CGFloat(x), y: firstY))
        }
        
        firstPath.addLine(to: CGPoint(x: bounds.size.width, y: bounds.size.height))
        firstPath.addLine(to: CGPoint(x: 0, y: bounds.size.height))
        firstPath.closeSubpath()
        frontLayer.path = firstPath

从0到以要绘制的宽度循环,绘制每一个像素点

updateWave方法中增加X轴偏移量,使其看起来在横向移动

offsetX += speed

第二个函数图像在增加X轴偏移量时和第一个区别一下,具体的细节调整可以根据需求来

效果图

RPReplay_Final1679275628