Advertisement
SwiftBin

Untitled

May 6th, 2021
1,196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 3.28 KB | None | 0 0
  1. final class WaveView: UIView {
  2.     private let waveColor = UIColor(red: 187/255, green: 215/255, blue: 235/255, alpha: 1.0)
  3.     private var phase: Double = 0.0
  4.    
  5.     private lazy var highSineWave: CAShapeLayer = {
  6.         let waveShape = CAShapeLayer()
  7.         waveShape.strokeColor = waveColor.cgColor
  8.         waveShape.fillColor = UIColor.clear.cgColor
  9.         waveShape.lineWidth = 2
  10.        
  11.         return waveShape
  12.     }()
  13.    
  14.     private lazy var lowSineWave: CAShapeLayer = {
  15.         let waveShape = CAShapeLayer()
  16.         waveShape.strokeColor = waveColor.cgColor
  17.         waveShape.fillColor = UIColor.clear.cgColor
  18.         waveShape.lineWidth = 2
  19.        
  20.         return waveShape
  21.     }()
  22.    
  23.     required init?(coder: NSCoder) {
  24.         fatalError("init(coder:) has not been implemented")
  25.     }
  26.    
  27.     override init(frame: CGRect) {
  28.         super.init(frame: frame)
  29.     }
  30.    
  31.     func startAnimate() {
  32.         addWaves()
  33.         animateWaves()
  34.     }
  35.    
  36.     func addWaves() {
  37.         layer.addSublayer(highSineWave)
  38.         layer.addSublayer(lowSineWave)
  39.     }
  40.    
  41.     func animateWaves() {
  42.         DispatchQueue.main.async {
  43.             UIView.animate(withDuration: 1.0, delay: 0.0, options: [.curveLinear], animations: {
  44.                 self.highSineWave.path = self.path(in: self.frame, frequency: 25, strength: 25)
  45.                 self.lowSineWave.path = self.path(in: self.frame, frequency: 15, strength: 10)
  46.                
  47.             }, completion: { (finished) in
  48.                 if self.phase >= 18.98 {
  49.                     self.phase = 0.0
  50.                 }
  51.                 self.phase += 0.001
  52.                
  53.                 self.animateWaves()
  54.             })
  55.         }
  56.        
  57.     }
  58.    
  59.     func path(in rect: CGRect, frequency: Double, strength: Double) -> CGPath {
  60.         let path = UIBezierPath()
  61.  
  62.         // calculate some important values up front
  63.         let width = Double(rect.width)
  64.         let height = Double(rect.height)
  65.         let midWidth = width / 2
  66.         let midHeight = height / 2
  67.         let oneOverMidWidth = 1 / midWidth
  68.        
  69.         // split our total width up based on the frequency
  70.         let wavelength = width / frequency
  71.  
  72.         // start at the left center
  73.         path.move(to: CGPoint(x: 0, y: midHeight))
  74.  
  75.         // now count across individual horizontal points one by one
  76.         for x in stride(from: 0, through: width, by: 1) {
  77.             // find our current position relative to the wavelength
  78.             let relativeX = x / wavelength
  79.  
  80.             // find how far we are from the horizontal center
  81.             let distanceFromMidWidth = x - midWidth
  82.  
  83.             // bring that into the range of -1 to 1
  84.             let normalDistance = oneOverMidWidth * distanceFromMidWidth
  85.  
  86.             let parabola = -(normalDistance * normalDistance) + 1
  87.  
  88.             // calculate the sine of that position, adding our phase offset
  89.             let sine = sin(relativeX + phase)
  90.  
  91.             // multiply that sine by our strength to determine final offset, then move it down to the middle of our view
  92.             let y = parabola * strength * sine + midHeight
  93.  
  94.             // add a line to here
  95.             path.addLine(to: CGPoint(x: x, y: y))
  96.         }
  97.  
  98.         return path.cgPath
  99.     }
  100. }
  101.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement