水波效果

2017-07-21  本文已影响33人  明月钓无痕
水波.gif

这里会使用到正弦函数进行计算:y=Asin(ωx+φ)。忘了的可以回去补补课了😆.我不会告诉你们我也回去补了课😂.
正弦型函数解析式:y=Asin(ωx+φ)
各常数值对函数图像的影响:
φ(初相位):决定波形与X轴位置关系或横向移动距离(左加右减)
ω:决定周期(最小正周期T=2π/|ω|)
A:决定峰值(即纵向拉伸压缩的倍数)
h:表示波形在Y轴的位置关系或纵向移动距离(上加下减)

下面看一下代码吧.

class JZWaveProgress: UIView {

    /** 进度 0-1 **/
    var progress: CGFloat! {
        didSet {
            y = bounds.height * (1 - progress)
            stopAnimation()
            startAnimation()
        }
    }
    /** 颜色 **/
    var waveColor: UIColor! = UIColor(colorLiteralRed: (34 / 255.0), green: (116 / 255.0), blue: (210 / 255.0), alpha: 1) {
        didSet {
            layer.borderColor = waveColor.cgColor
            layer.borderWidth = 1
        }
    
    }
    /** 波峰 **/
    var waveCrest: CGFloat? = 5.0
    /** 进度 **/
    var text: String? {
        didSet {
            textLabel.text = text!
        }
    }
    
    var font: UIFont? {
        didSet {
            textLabel.font = font
            textLabel.frame.size.height = (font?.pointSize)!
            textLabel.frame.origin.y = self.bounds.midY - textLabel.frame.height * 0.5
        }
    }
    
    var textColor: UIColor? {
        didSet {
            textLabel.textColor = textColor
        }
    }
    
    var speed: CGFloat! = 1
    
    fileprivate var y: CGFloat!

    fileprivate var offset: CGFloat! = 0
    
    fileprivate var timer: CADisplayLink!
    
    fileprivate lazy var waveLayer: CAShapeLayer  = {
        let waveLayer = CAShapeLayer()
        waveLayer.frame = self.bounds
        waveLayer.fillColor = self.waveColor.cgColor
        self.layer.addSublayer(waveLayer)
        return waveLayer
    }()
    
    fileprivate lazy var textLabel: UILabel = {
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.width, height: 17))
        label.textAlignment = .center
        label.frame.origin.y = self.bounds.midY - label.frame.height * 0.5
        self.addSubview(label)
        return label
    }()
    
    
    
    override init(frame: CGRect) {
        
        super.init(frame: frame)
        let wh = min(frame.width, frame.height)
       
        bounds = CGRect(x: 0, y: 0, width: wh, height: wh)
        y = bounds.height
        layer.cornerRadius = wh * 0.5
        layer.masksToBounds = true
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}


extension JZWaveProgress {
    
    fileprivate func startAnimation() {
        let timer = CADisplayLink(target: self, selector: #selector(waveAnimation))
        self.timer = timer
        timer.add(to: RunLoop.main, forMode: .commonModes)
    }
    
    fileprivate func stopAnimation() {
        timer?.invalidate()
        timer = nil
    }
    
    @objc fileprivate func waveAnimation() {
        // 设置没有波纹
        if progress == 0.0 || progress == 1.0 {
            speed = 0
        }
        
        offset = offset + speed
        // firstWave:   y=Asin(ωx+φ) + h
        let firstWave = CGMutablePath()
        
        let cycle = Double(offset * CGFloat(Float.pi) * 2 / bounds.width)

        let width = bounds.width
        let height = bounds.height
        let startOffSetY = waveCrest! * CGFloat(sin(cycle))
        
        var originOffSetY: CGFloat = 0
        firstWave.move(to: CGPoint(x: 0, y: startOffSetY))
        
        for i in 0...Int(floorf(Float(bounds.width))) {
            
            originOffSetY = waveCrest! * CGFloat(sin(cycle + Double.pi * 2 / Double(width) * Double(i))) + y
            firstWave.addLine(to: CGPoint(x: CGFloat(i), y: originOffSetY))
            
        }
        
        firstWave.addLine(to: CGPoint(x: width, y: originOffSetY))
        firstWave.addLine(to: CGPoint(x: width, y: height))
        firstWave.addLine(to: CGPoint(x: 0, y: height))
        firstWave.addLine(to: CGPoint(x: 0, y: startOffSetY))
        firstWave.closeSubpath()
        
        waveLayer.path = firstWave
        waveLayer.fillColor = waveColor.cgColor
        
        bringSubview(toFront: textLabel)
    }
    
}

ps: 如果需要条波纹的话,多加几条 path 就好了,前提是不要让初相位一样哦

上一篇 下一篇

猜你喜欢

热点阅读