From e8f6fb6c056584156b97fa3c27ded2e4027e4e5e Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 12 Jun 2020 22:09:27 +0400 Subject: [PATCH] Mege patch --- submodules/TelegramUI/Sources/BlobView.swift | 115 ++++++++++-------- .../Sources/ChatTextInputPanelNode.swift | 14 ++- 2 files changed, 73 insertions(+), 56 deletions(-) diff --git a/submodules/TelegramUI/Sources/BlobView.swift b/submodules/TelegramUI/Sources/BlobView.swift index cb8abb19bb..d4af62730a 100644 --- a/submodules/TelegramUI/Sources/BlobView.swift +++ b/submodules/TelegramUI/Sources/BlobView.swift @@ -14,25 +14,31 @@ final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDecoration pointsCount: 8, minRandomness: 0.1, maxRandomness: 1, - idleSize: 1, minSpeed: 0.2, - maxSpeed: 1 + maxSpeed: 1, + minScale: 0.56, + maxScale: 0.56, + scaleSpeed: 0 ) private let mediumBlob = BlobView( pointsCount: 8, minRandomness: 1, maxRandomness: 2, - idleSize: 0.667, - minSpeed: 1, - maxSpeed: 8 + minSpeed: 3, + maxSpeed: 8, + minScale: 0.67, + maxScale: 0.9, + scaleSpeed: 0.1 ) private let bigBlob = BlobView( pointsCount: 8, minRandomness: 1, maxRandomness: 2, - idleSize: 0.667, - minSpeed: 1, - maxSpeed: 8 + minSpeed: 3, + maxSpeed: 8, + minScale: 0.67, + maxScale: 1, + scaleSpeed: 0.1 ) override init(frame: CGRect) { @@ -66,27 +72,16 @@ final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDecoration override func layoutSubviews() { super.layoutSubviews() - func frameForBlobSize(_ blobSize: CGFloat) -> CGRect { - let blobWidth = bounds.width * blobSize - let blobHeight = bounds.height * blobSize - return CGRect( - x: (bounds.width - blobWidth) / 2, - y: (bounds.height - blobHeight) / 2, - width: blobWidth, - height: blobHeight - ) - } - let isInitial = smallBlob.frame == .zero - smallBlob.frame = frameForBlobSize(0.56) - mediumBlob.frame = frameForBlobSize(0.9) - bigBlob.frame = frameForBlobSize(1) + smallBlob.frame = bounds + mediumBlob.frame = bounds + bigBlob.frame = bounds if isInitial { - smallBlob.animateToNewShape() - mediumBlob.animateToNewShape() - bigBlob.animateToNewShape() + smallBlob.startAnimating() + mediumBlob.startAnimating() + bigBlob.startAnimating() } } } @@ -94,7 +89,6 @@ final class VoiceBlobView: UIView, TGModernConversationInputMicButtonDecoration final class BlobView: UIView { let pointsCount: Int - let idleSize: CGFloat let smoothness: CGFloat let minRandomness: CGFloat @@ -103,19 +97,19 @@ final class BlobView: UIView { let minSpeed: CGFloat let maxSpeed: CGFloat + let minScale: CGFloat + let maxScale: CGFloat + let scaleSpeed: CGFloat + var level: CGFloat = 0 { didSet { - let shouldInterruptAnimation = abs(level - oldValue) > 0.3 - - debouncedLevel = max(level, debouncedLevel) - - if shouldInterruptAnimation { - animateToNewShape() - } + speedLevel = max(level, speedLevel) + scaleLevel = max(level, scaleLevel) } } - private var debouncedLevel: CGFloat = 0 + private var speedLevel: CGFloat = 0 + private var scaleLevel: CGFloat = 0 private let shapeLayer: CAShapeLayer = { let layer = CAShapeLayer() @@ -150,16 +144,20 @@ final class BlobView: UIView { pointsCount: Int, minRandomness: CGFloat, maxRandomness: CGFloat, - idleSize: CGFloat, minSpeed: CGFloat, - maxSpeed: CGFloat + maxSpeed: CGFloat, + minScale: CGFloat, + maxScale: CGFloat, + scaleSpeed: CGFloat ) { self.pointsCount = pointsCount self.minRandomness = minRandomness self.maxRandomness = maxRandomness - self.idleSize = idleSize self.minSpeed = minSpeed self.maxSpeed = maxSpeed + self.minScale = minScale + self.maxScale = maxScale + self.scaleSpeed = scaleSpeed let angle = (CGFloat.pi * 2) / CGFloat(pointsCount) self.smoothness = ((4 / 3) * tan(angle / 4)) / sin(angle / 2) / 2 @@ -167,6 +165,8 @@ final class BlobView: UIView { super.init(frame: .zero) layer.addSublayer(shapeLayer) + + shapeLayer.transform = CATransform3DMakeScale(minScale, minScale, 1) } required init?(coder: NSCoder) { @@ -177,16 +177,29 @@ final class BlobView: UIView { shapeLayer.fillColor = color.cgColor } - func animateToNewShape() { - let minSize = CGSize( - width: bounds.size.width * idleSize, - height: bounds.size.height * idleSize - ) - let currentSize = CGSize( - width: minSize.width + (bounds.size.width - minSize.width) * debouncedLevel, - height: minSize.height + (bounds.size.height - minSize.height) * debouncedLevel - ) + func startAnimating() { + animateToNewShape() + animateToNewScale() + } + + func animateToNewScale() { + shapeLayer.pop_removeAnimation(forKey: "scale") + let currentScale = minScale + (maxScale - minScale) * scaleLevel + let scaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)! + scaleAnimation.toValue = CGPoint(x: currentScale, y: currentScale) + scaleAnimation.duration = CFTimeInterval(scaleSpeed) + scaleAnimation.completionBlock = { [weak self] animation, finished in + if finished { + self?.animateToNewScale() + } + } + shapeLayer.pop_add(scaleAnimation, forKey: "scale") + + scaleLevel = 0 + } + + func animateToNewShape() { if pop_animation(forKey: "blob") != nil { fromPoints = currentPoints toPoints = nil @@ -194,10 +207,10 @@ final class BlobView: UIView { } if fromPoints == nil { - fromPoints = generateNextBlob(for: currentSize) + fromPoints = generateNextBlob(for: bounds.size) } if toPoints == nil { - toPoints = generateNextBlob(for: currentSize) + toPoints = generateNextBlob(for: bounds.size) } let animation = POPBasicAnimation() @@ -220,19 +233,19 @@ final class BlobView: UIView { self?.animateToNewShape() } } - animation.duration = CFTimeInterval(1 / (minSpeed + (maxSpeed - minSpeed) * debouncedLevel)) + animation.duration = CFTimeInterval(1 / (minSpeed + (maxSpeed - minSpeed) * speedLevel)) animation.timingFunction = CAMediaTimingFunction(name: .linear) animation.fromValue = 0 animation.toValue = 1 pop_add(animation, forKey: "blob") - debouncedLevel = 0 + speedLevel = 0 } // MARK: Helpers private func generateNextBlob(for size: CGSize) -> [CGPoint] { - let randomness = minRandomness + (maxRandomness - minRandomness) * debouncedLevel + let randomness = minRandomness + (maxRandomness - minRandomness) * speedLevel return blob(pointsCount: pointsCount, randomness: randomness) .map { return CGPoint( diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 1b1c16928d..0c053dc60e 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -1021,12 +1021,16 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { audioRecordingTimeNode.audioRecorder = recorder var animateDotAppearing = false + let audioRecordingDotNode: AnimationNode + if let currentAudioRecordingDotNode = self.audioRecordingDotNode, !currentAudioRecordingDotNode.played { + audioRecordingDotNode = currentAudioRecordingDotNode + } else { + self.audioRecordingDotNode?.removeFromSupernode() + audioRecordingDotNode = AnimationNode(animation: "voicebin") + self.audioRecordingDotNode = audioRecordingDotNode + self.addSubnode(audioRecordingDotNode) + } - self.audioRecordingDotNode?.removeFromSupernode() - let audioRecordingDotNode = AnimationNode(animation: "voicebin") - self.audioRecordingDotNode = audioRecordingDotNode - self.addSubnode(audioRecordingDotNode) - animateDotAppearing = transition.isAnimated audioRecordingDotNode.frame = CGRect(origin: CGPoint(x: leftInset + 2.0 - UIScreenPixel, y: panelHeight - 44 + 1), size: CGSize(width: 40.0, height: 40))