forked from mozilla-mobile/focus-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WaveView.swift
96 lines (80 loc) · 4.04 KB
/
WaveView.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
import UIKit
private let ActiveInactiveTransitionStep: CGFloat = 0.05
private let ColorTransitionStep: Float = 0.002
private let PrimaryWaveActiveColors = [UIConstants.colors.focusOrange, UIConstants.colors.focusRed, UIConstants.colors.focusViolet, UIConstants.colors.focusLightBlue, UIConstants.colors.focusViolet, UIConstants.colors.focusRed]
private let PrimaryWaveColorCount = PrimaryWaveActiveColors.count
private let PrimaryWaveInactiveColor = UIColor.gray
private let SecondaryWaveColor = UIColor.gray
private let WaveLevel: CGFloat = 0.8
private let PrimaryWaveFrequency: CGFloat = 1.2
private let SecondaryWaveFrequency: CGFloat = 0.8
private let BaseDeviceRatio: CGFloat = 1.875
class WaveView: UIView {
var active = true
fileprivate let frontWaveView = SCSiriWaveformView()
fileprivate let backWaveView = SCSiriWaveformView()
fileprivate var waveLevel: CGFloat = 0
fileprivate var colorLerp: Float = 0
init() {
super.init(frame: CGRect.zero)
backWaveView.backgroundColor = UIColor.clear
backWaveView.phaseShift = -0.022
backWaveView.primaryWaveLineWidth = 0.5
backWaveView.primaryWaveColor = PrimaryWaveInactiveColor
backWaveView.secondaryWaveLineWidth = 0.5
backWaveView.secondaryWaveColor = UIColor.darkGray
backWaveView.update(withLevel: 0)
addSubview(backWaveView)
frontWaveView.backgroundColor = UIColor.clear
frontWaveView.phaseShift = -0.02
frontWaveView.primaryWaveLineWidth = 2
frontWaveView.primaryWaveColor = PrimaryWaveInactiveColor
frontWaveView.secondaryWaveLineWidth = 0.5
frontWaveView.secondaryWaveColor = SecondaryWaveColor
frontWaveView.update(withLevel: 0)
addSubview(frontWaveView)
frontWaveView.snp.makeConstraints { make in
make.top.bottom.equalTo(self)
make.leading.trailing.equalTo(self).inset(-40)
}
backWaveView.snp.makeConstraints { make in
make.top.bottom.equalTo(self)
make.leading.trailing.equalTo(self).inset(-15)
}
clipsToBounds = true
let displayLink = CADisplayLink(target: self, selector: #selector(WaveView.displayLink(_:)))
displayLink.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func displayLink(_ sender: CADisplayLink) {
colorLerp = (colorLerp + ColorTransitionStep).truncatingRemainder(dividingBy: Float(PrimaryWaveColorCount))
let colorIndex = Int(colorLerp)
let lerp = CGFloat(colorLerp - Float(colorIndex))
let fromColor = PrimaryWaveActiveColors[colorIndex]
let toColor = PrimaryWaveActiveColors[(colorIndex + 1) % PrimaryWaveColorCount]
let currentColor = fromColor.lerp(toColor: toColor, step: lerp)
if active && waveLevel < WaveLevel {
waveLevel += ActiveInactiveTransitionStep
frontWaveView.primaryWaveColor = PrimaryWaveInactiveColor.lerp(toColor: currentColor, step: waveLevel / WaveLevel)
} else if !active && waveLevel > 0 {
waveLevel -= ActiveInactiveTransitionStep
frontWaveView.primaryWaveColor = currentColor.lerp(toColor: PrimaryWaveInactiveColor, step: (WaveLevel - waveLevel) / WaveLevel)
} else if active {
frontWaveView.primaryWaveColor = currentColor
}
backWaveView.update(withLevel: waveLevel - 0.1)
frontWaveView.update(withLevel: waveLevel)
}
override func layoutSubviews() {
super.layoutSubviews()
let freqMultiplier: CGFloat = bounds.width / bounds.height / BaseDeviceRatio
frontWaveView.frequency = PrimaryWaveFrequency * freqMultiplier
backWaveView.frequency = SecondaryWaveFrequency * freqMultiplier
}
}