mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
175 lines
5.2 KiB
Swift
175 lines
5.2 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import AsyncDisplayKit
|
|
import Display
|
|
import CallScreen
|
|
import MetalEngine
|
|
|
|
final class VoiceBlobView: UIView {
|
|
//private let mediumBlob: BlobView
|
|
//private let bigBlob: BlobView
|
|
|
|
private let blobsLayer: CallBlobsLayer
|
|
|
|
private let maxLevel: CGFloat
|
|
|
|
private var displayLinkAnimator: ConstantDisplayLinkAnimator?
|
|
|
|
private var audioLevel: CGFloat = 0.0
|
|
var presentationAudioLevel: CGFloat = 0.0
|
|
|
|
var scaleUpdated: ((CGFloat) -> Void)? {
|
|
didSet {
|
|
//self.bigBlob.scaleUpdated = self.scaleUpdated
|
|
}
|
|
}
|
|
|
|
private(set) var isAnimating = false
|
|
|
|
public typealias BlobRange = (min: CGFloat, max: CGFloat)
|
|
|
|
private let hierarchyTrackingNode: HierarchyTrackingNode
|
|
private var isCurrentlyInHierarchy = true
|
|
|
|
init(
|
|
frame: CGRect,
|
|
maxLevel: CGFloat,
|
|
mediumBlobRange: BlobRange,
|
|
bigBlobRange: BlobRange
|
|
) {
|
|
var updateInHierarchy: ((Bool) -> Void)?
|
|
self.hierarchyTrackingNode = HierarchyTrackingNode({ value in
|
|
updateInHierarchy?(value)
|
|
})
|
|
|
|
self.maxLevel = maxLevel
|
|
|
|
/*self.mediumBlob = BlobView(
|
|
pointsCount: 8,
|
|
minRandomness: 1,
|
|
maxRandomness: 1,
|
|
minSpeed: 0.9,
|
|
maxSpeed: 4.0,
|
|
minScale: mediumBlobRange.min,
|
|
maxScale: mediumBlobRange.max
|
|
)
|
|
self.bigBlob = BlobView(
|
|
pointsCount: 8,
|
|
minRandomness: 1,
|
|
maxRandomness: 1,
|
|
minSpeed: 1.0,
|
|
maxSpeed: 4.4,
|
|
minScale: bigBlobRange.min,
|
|
maxScale: bigBlobRange.max
|
|
)*/
|
|
|
|
self.blobsLayer = CallBlobsLayer()
|
|
|
|
super.init(frame: frame)
|
|
|
|
self.addSubnode(self.hierarchyTrackingNode)
|
|
|
|
//self.addSubview(self.bigBlob)
|
|
//self.addSubview(self.mediumBlob)
|
|
self.layer.addSublayer(self.blobsLayer)
|
|
|
|
self.displayLinkAnimator = ConstantDisplayLinkAnimator() { [weak self] in
|
|
guard let strongSelf = self else { return }
|
|
|
|
if !strongSelf.isCurrentlyInHierarchy {
|
|
return
|
|
}
|
|
|
|
strongSelf.presentationAudioLevel = strongSelf.presentationAudioLevel * 0.9 + strongSelf.audioLevel * 0.1
|
|
strongSelf.updateAudioLevel()
|
|
|
|
//strongSelf.mediumBlob.level = strongSelf.presentationAudioLevel
|
|
//strongSelf.bigBlob.level = strongSelf.presentationAudioLevel
|
|
}
|
|
|
|
updateInHierarchy = { [weak self] value in
|
|
if let strongSelf = self {
|
|
strongSelf.isCurrentlyInHierarchy = value
|
|
}
|
|
}
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
public func setColor(_ color: UIColor) {
|
|
//self.mediumBlob.setColor(color.withAlphaComponent(0.5))
|
|
//self.bigBlob.setColor(color.withAlphaComponent(0.21))
|
|
}
|
|
|
|
public func updateLevel(_ level: CGFloat, immediately: Bool) {
|
|
let normalizedLevel = min(1, max(level / maxLevel, 0))
|
|
|
|
//self.mediumBlob.updateSpeedLevel(to: normalizedLevel)
|
|
//self.bigBlob.updateSpeedLevel(to: normalizedLevel)
|
|
|
|
self.audioLevel = normalizedLevel
|
|
if immediately {
|
|
self.presentationAudioLevel = normalizedLevel
|
|
}
|
|
}
|
|
|
|
private func updateAudioLevel() {
|
|
let additionalAvatarScale = CGFloat(max(0.0, min(self.presentationAudioLevel * 18.0, 5.0)) * 0.05)
|
|
let blobAmplificationFactor: CGFloat = 2.0
|
|
let blobScale = 1.0 + additionalAvatarScale * blobAmplificationFactor
|
|
self.blobsLayer.transform = CATransform3DMakeScale(blobScale, blobScale, 1.0)
|
|
|
|
self.scaleUpdated?(blobScale)
|
|
}
|
|
|
|
public func startAnimating() {
|
|
guard !self.isAnimating else { return }
|
|
self.isAnimating = true
|
|
|
|
self.updateBlobsState()
|
|
|
|
self.displayLinkAnimator?.isPaused = false
|
|
}
|
|
|
|
public func stopAnimating() {
|
|
self.stopAnimating(duration: 0.15)
|
|
}
|
|
|
|
public func stopAnimating(duration: Double) {
|
|
guard isAnimating else { return }
|
|
self.isAnimating = false
|
|
|
|
self.updateBlobsState()
|
|
|
|
self.displayLinkAnimator?.isPaused = true
|
|
}
|
|
|
|
private func updateBlobsState() {
|
|
/*if self.isAnimating {
|
|
if self.mediumBlob.frame.size != .zero {
|
|
self.mediumBlob.startAnimating()
|
|
self.bigBlob.startAnimating()
|
|
}
|
|
} else {
|
|
self.mediumBlob.stopAnimating()
|
|
self.bigBlob.stopAnimating()
|
|
}*/
|
|
}
|
|
|
|
override public func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
//self.mediumBlob.frame = bounds
|
|
//self.bigBlob.frame = bounds
|
|
|
|
let blobsFrame = bounds.insetBy(dx: floor(bounds.width * 0.12), dy: floor(bounds.height * 0.12))
|
|
self.blobsLayer.position = blobsFrame.center
|
|
self.blobsLayer.bounds = CGRect(origin: CGPoint(), size: blobsFrame.size)
|
|
|
|
self.updateBlobsState()
|
|
}
|
|
}
|
|
|