Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- final class WaveView: UIView {
- private let waveColor = UIColor(red: 187/255, green: 215/255, blue: 235/255, alpha: 1.0)
- private var phase: Double = 0.0
- private lazy var highSineWave: CAShapeLayer = {
- let waveShape = CAShapeLayer()
- waveShape.strokeColor = waveColor.cgColor
- waveShape.fillColor = UIColor.clear.cgColor
- waveShape.lineWidth = 2
- return waveShape
- }()
- private lazy var lowSineWave: CAShapeLayer = {
- let waveShape = CAShapeLayer()
- waveShape.strokeColor = waveColor.cgColor
- waveShape.fillColor = UIColor.clear.cgColor
- waveShape.lineWidth = 2
- return waveShape
- }()
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override init(frame: CGRect) {
- super.init(frame: frame)
- }
- func startAnimate() {
- addWaves()
- animateWaves()
- }
- func addWaves() {
- layer.addSublayer(highSineWave)
- layer.addSublayer(lowSineWave)
- }
- func animateWaves() {
- DispatchQueue.main.async {
- UIView.animate(withDuration: 1.0, delay: 0.0, options: [.curveLinear], animations: {
- self.highSineWave.path = self.path(in: self.frame, frequency: 25, strength: 25)
- self.lowSineWave.path = self.path(in: self.frame, frequency: 15, strength: 10)
- }, completion: { (finished) in
- if self.phase >= 18.98 {
- self.phase = 0.0
- }
- self.phase += 0.001
- self.animateWaves()
- })
- }
- }
- func path(in rect: CGRect, frequency: Double, strength: Double) -> CGPath {
- let path = UIBezierPath()
- // calculate some important values up front
- let width = Double(rect.width)
- let height = Double(rect.height)
- let midWidth = width / 2
- let midHeight = height / 2
- let oneOverMidWidth = 1 / midWidth
- // split our total width up based on the frequency
- let wavelength = width / frequency
- // start at the left center
- path.move(to: CGPoint(x: 0, y: midHeight))
- // now count across individual horizontal points one by one
- for x in stride(from: 0, through: width, by: 1) {
- // find our current position relative to the wavelength
- let relativeX = x / wavelength
- // find how far we are from the horizontal center
- let distanceFromMidWidth = x - midWidth
- // bring that into the range of -1 to 1
- let normalDistance = oneOverMidWidth * distanceFromMidWidth
- let parabola = -(normalDistance * normalDistance) + 1
- // calculate the sine of that position, adding our phase offset
- let sine = sin(relativeX + phase)
- // multiply that sine by our strength to determine final offset, then move it down to the middle of our view
- let y = parabola * strength * sine + midHeight
- // add a line to here
- path.addLine(to: CGPoint(x: x, y: y))
- }
- return path.cgPath
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement