diff --git a/submodules/Display/Source/CAAnimationUtils.swift b/submodules/Display/Source/CAAnimationUtils.swift index 5682fc240e..4aecee5b73 100644 --- a/submodules/Display/Source/CAAnimationUtils.swift +++ b/submodules/Display/Source/CAAnimationUtils.swift @@ -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 - animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName(rawValue: timingFunction)) + 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) diff --git a/submodules/Display/Source/ContainedViewLayoutTransition.swift b/submodules/Display/Source/ContainedViewLayoutTransition.swift index 6313fb29c3..bfdcc179a1 100644 --- a/submodules/Display/Source/ContainedViewLayoutTransition.swift +++ b/submodules/Display/Source/ContainedViewLayoutTransition.swift @@ -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) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift index d9c0e924bd..69a04531cc 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift @@ -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) } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatOverlayController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatOverlayController.swift index b76c49faa3..edf4d0fe1c 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatOverlayController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatOverlayController.swift @@ -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) }) diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 225c5cc1ea..2555a99f5b 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -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(