Voice Chat UI improvements

This commit is contained in:
Ilya Laktyushin 2020-12-15 01:03:48 +04:00
parent d529378a74
commit b874342aff
5 changed files with 31 additions and 20 deletions

View File

@ -127,7 +127,7 @@ public extension CALayer {
self.add(animationGroup, forKey: key)
}
func animateKeyframes(values: [AnyObject], duration: Double, keyPath: String, timingFunction: String = CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: Bool = true, additive: Bool = false, completion: ((Bool) -> Void)? = nil) {
func animateKeyframes(values: [AnyObject], duration: Double, keyPath: String, timingFunction: String = CAMediaTimingFunctionName.linear.rawValue, mediaTimingFunction: CAMediaTimingFunction? = nil, removeOnCompletion: Bool = true, additive: Bool = false, completion: ((Bool) -> Void)? = nil) {
let k = Float(UIView.animationDurationFactor())
var speed: Float = 1.0
if k != 0 && k != 1 {
@ -150,7 +150,11 @@ public extension CALayer {
animation.speed = speed
animation.duration = duration
animation.isAdditive = additive
if let mediaTimingFunction = mediaTimingFunction {
animation.timingFunction = mediaTimingFunction
} else {
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName(rawValue: timingFunction))
}
animation.isRemovedOnCompletion = removeOnCompletion
if let completion = completion {
animation.delegate = CALayerAnimationDelegate(animation: animation, completion: completion)

View File

@ -477,7 +477,7 @@ public extension ContainedViewLayoutTransition {
}
}
func updateAlpha(node: ASDisplayNode, alpha: CGFloat, beginWithCurrentState: Bool = false, force: Bool = false, completion: ((Bool) -> Void)? = nil) {
func updateAlpha(node: ASDisplayNode, alpha: CGFloat, beginWithCurrentState: Bool = false, force: Bool = false, delay: Double = 0.0, completion: ((Bool) -> Void)? = nil) {
if node.alpha.isEqual(to: alpha) && !force {
if let completion = completion {
completion(true)
@ -499,7 +499,7 @@ public extension ContainedViewLayoutTransition {
previousAlpha = node.alpha
}
node.alpha = alpha
node.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction, completion: { result in
node.layer.animateAlpha(from: previousAlpha, to: alpha, duration: duration, delay: delay, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction, completion: { result in
if let completion = completion {
completion(result)
}
@ -670,7 +670,7 @@ public extension ContainedViewLayoutTransition {
}
}
func updateTransformScale(node: ASDisplayNode, scale: CGFloat, beginWithCurrentState: Bool = false, completion: ((Bool) -> Void)? = nil) {
func updateTransformScale(node: ASDisplayNode, scale: CGFloat, beginWithCurrentState: Bool = false, delay: Double = 0.0, completion: ((Bool) -> Void)? = nil) {
let t = node.layer.transform
let currentScale = sqrt((t.m11 * t.m11) + (t.m12 * t.m12) + (t.m13 * t.m13))
if currentScale.isEqual(to: scale) {
@ -695,7 +695,7 @@ public extension ContainedViewLayoutTransition {
previousScale = currentScale
}
node.layer.transform = CATransform3DMakeScale(scale, scale, 1.0)
node.layer.animateScale(from: previousScale, to: scale, duration: duration, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction, completion: { result in
node.layer.animateScale(from: previousScale, to: scale, duration: duration, delay: delay, timingFunction: curve.timingFunction, mediaTimingFunction: curve.mediaTimingFunction, completion: { result in
if let completion = completion {
completion(result)
}
@ -729,7 +729,7 @@ public extension ContainedViewLayoutTransition {
}
}
func updateSublayerTransformScale(node: ASDisplayNode, scale: CGFloat, completion: ((Bool) -> Void)? = nil) {
func updateSublayerTransformScale(node: ASDisplayNode, scale: CGFloat, delay: Double = 0.0, completion: ((Bool) -> Void)? = nil) {
if !node.isNodeLoaded {
node.subnodeTransform = CATransform3DMakeScale(scale, scale, 1.0)
completion?(true)
@ -752,7 +752,7 @@ public extension ContainedViewLayoutTransition {
}
case let .animated(duration, curve):
node.layer.sublayerTransform = CATransform3DMakeScale(scale, scale, 1.0)
node.layer.animate(from: NSValue(caTransform3D: t), to: NSValue(caTransform3D: node.layer.sublayerTransform), keyPath: "sublayerTransform", timingFunction: curve.timingFunction, duration: duration, delay: 0.0, mediaTimingFunction: curve.mediaTimingFunction, removeOnCompletion: true, additive: false, completion: {
node.layer.animate(from: NSValue(caTransform3D: t), to: NSValue(caTransform3D: node.layer.sublayerTransform), keyPath: "sublayerTransform", timingFunction: curve.timingFunction, duration: duration, delay: delay, mediaTimingFunction: curve.mediaTimingFunction, removeOnCompletion: true, additive: false, completion: {
result in
if let completion = completion {
completion(result)

View File

@ -200,18 +200,20 @@ final class VoiceChatActionButton: HighlightTrackingButtonNode {
break
}
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.2, curve: .easeInOut) : .immediate
if snap {
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.2, curve: .easeInOut) : .immediate
transition.updateTransformScale(node: self.backgroundNode, scale: active ? 0.75 : 0.5)
transition.updateTransformScale(node: self.iconNode, scale: 0.5)
transition.updateAlpha(node: self.titleLabel, alpha: 0.0)
transition.updateAlpha(node: self.subtitleLabel, alpha: 0.0)
transition.updateAlpha(layer: self.backgroundNode.maskProgressLayer, alpha: 0.0)
} else {
transition.updateTransformScale(node: self.backgroundNode, scale: small ? 0.85 : 1.0)
transition.updateTransformScale(node: self.iconNode, scale: self.pressing ? 0.9 : 1.0)
transition.updateAlpha(node: self.titleLabel, alpha: 1.0)
transition.updateAlpha(node: self.subtitleLabel, alpha: 1.0)
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.35, curve: .easeInOut) : .immediate
transition.updateTransformScale(node: self.backgroundNode, scale: small ? 0.85 : 1.0, delay: 0.12)
transition.updateTransformScale(node: self.iconNode, scale: self.pressing ? 0.9 : 1.0, delay: 0.12)
transition.updateAlpha(node: self.titleLabel, alpha: 1.0, delay: 0.1)
transition.updateAlpha(node: self.subtitleLabel, alpha: 1.0, delay: 0.1)
transition.updateAlpha(layer: self.backgroundNode.maskProgressLayer, alpha: 1.0)
}

View File

@ -117,11 +117,13 @@ public final class VoiceChatOverlayController: ViewController {
leftButton?.textNode.layer.removeAllAnimations()
leftButton?.layer.removeAllAnimations()
})
leftButton.layer.animateScale(from: 1.0, to: 0.5, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
rightButton.layer.animatePosition(from: rightButton.position, to: center, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak rightButton] _ in
rightButton?.isHidden = true
rightButton?.textNode.layer.removeAllAnimations()
rightButton?.layer.removeAllAnimations()
})
rightButton.layer.animateScale(from: 1.0, to: 0.5, duration: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
leftButton.textNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false)
rightButton.textNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.1, removeOnCompletion: false)
@ -197,7 +199,7 @@ public final class VoiceChatOverlayController: ViewController {
} else {
self.animating = true
let sourcePoint = actionButton.position
var midPoint = CGPoint(x: (sourcePoint.x + targetPosition.x) / 2.0 - 25.0, y: (sourcePoint.y + targetPosition.y) / 2.0 + 25.0)
var midPoint = CGPoint(x: (sourcePoint.x + targetPosition.x) / 2.0 - 30.0, y: (sourcePoint.y + targetPosition.y) / 2.0 + 25.0)
if sourcePoint.y < layout.size.height - 100.0 {
midPoint.x = (sourcePoint.x + targetPosition.x) / 2.0 + 30.0
midPoint.y = (sourcePoint.y + targetPosition.y) / 2.0 + 40.0
@ -226,18 +228,21 @@ public final class VoiceChatOverlayController: ViewController {
let center = CGPoint(x: actionButton.frame.width / 2.0, y: actionButton.frame.height / 2.0)
leftButton.isHidden = false
leftButton.layer.animatePosition(from: center, to: leftButtonPosition, duration: 0.25, delay: 0.12, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false)
leftButton.layer.animatePosition(from: center, to: leftButtonPosition, duration: 0.28, delay: 0.12, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false)
rightButton.isHidden = false
rightButton.layer.animatePosition(from: center, to: rightButtonPosition, duration: 0.25, delay: 0.12, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false)
rightButton.layer.animatePosition(from: center, to: rightButtonPosition, duration: 0.28, delay: 0.12, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false)
leftButton.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1, delay: 0.1)
rightButton.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1, delay: 0.1)
leftButton.layer.animateScale(from: 0.5, to: 1.0, duration: 0.28, delay: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
rightButton.layer.animateScale(from: 0.5, to: 1.0, duration: 0.28, delay: 0.15, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue)
leftButton.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1, delay: 0.15)
rightButton.textNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1, delay: 0.15)
}
actionButton.update(snap: false, animated: true)
actionButton.position = targetPosition
actionButton.layer.animateKeyframes(values: keyframes, duration: 0.37, keyPath: "position", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, completion: { _ in
actionButton.layer.animateKeyframes(values: keyframes, duration: 0.48, keyPath: "position", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, mediaTimingFunction: CAMediaTimingFunction(controlPoints: 0.5, 1.1+Float(1.0/3.0), 1, 1), completion: { _ in
self.animating = false
completion(false)
})

View File

@ -618,7 +618,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
deliveryFailedColors: PresentationThemeFillForeground(fillColor: UIColor(rgb: 0xff3b30), foregroundColor: UIColor(rgb: 0xffffff)),
mediaHighlightOverlayColor: UIColor(rgb: 0xffffff, alpha: 0.6),
stickerPlaceholderColor: PresentationThemeVariableColor(withWallpaper: serviceBackgroundColor.withAlphaComponent(0.3), withoutWallpaper: UIColor(rgb: 0xf7f7f7)),
stickerPlaceholderShimmerColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0xffffff, alpha: 0.2), withoutWallpaper: UIColor(rgb: 0xffffff, alpha: 0.5))
stickerPlaceholderShimmerColor: PresentationThemeVariableColor(withWallpaper: UIColor(rgb: 0xffffff, alpha: 0.2), withoutWallpaper: UIColor(rgb: 0x000000, alpha: 0.1))
)
let serviceMessage = PresentationThemeServiceMessage(