美文网首页
水波效果

水波效果

作者: 明月钓无痕 | 来源:发表于2017-07-21 18:05 被阅读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 就好了,前提是不要让初相位一样哦

    相关文章

      网友评论

          本文标题:水波效果

          本文链接:https://www.haomeiwen.com/subject/uypekxtx.html