From 97bede7cda4ac9f428ea09547e86c7d14e993a15 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Thu, 12 Sep 2019 21:40:32 +0400 Subject: [PATCH] Animation experiment --- .../Sources/Node/ChatListItem.swift | 2 +- .../ContextUI/Sources/ContextController.swift | 41 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 622f2f6bdd..a8225ed158 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -490,7 +490,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { guard let strongSelf = self, let item = strongSelf.item else { return } - item.interaction.activateChatPreview(item, strongSelf, gesture) + item.interaction.activateChatPreview(item, strongSelf.contextContainer, gesture) } } diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index 57b7d3244e..d890ae4961 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -556,14 +556,29 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi self.contentContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2 * animationDurationFactor, completion: { [weak self] _ in self?.contentContainerNode.allowsGroupOpacity = false }) - self.contentContainerNode.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping) if let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame { let actionsSideInset: CGFloat = 11.0 let localSourceFrame = self.view.convert(CGRect(origin: CGPoint(x: originalProjectedContentViewFrame.1.minX, y: originalProjectedContentViewFrame.1.minY), size: CGSize(width: originalProjectedContentViewFrame.1.width, height: originalProjectedContentViewFrame.1.height)), to: self.scrollNode.view) - self.actionsContainerNode.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: localSourceFrame.center.x - self.actionsContainerNode.position.x, y: localSourceFrame.center.y - self.actionsContainerNode.position.y)), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true) + + self.contentContainerNode.layer.animateSpring(from: min(localSourceFrame.width / self.contentContainerNode.frame.width, localSourceFrame.height / self.contentContainerNode.frame.height) as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping) + let contentContainerOffset = CGPoint(x: localSourceFrame.center.x - self.contentContainerNode.frame.center.x, y: localSourceFrame.center.y - self.contentContainerNode.frame.center.y) + if let contentNode = self.contentContainerNode.contentNode, case let .controller(controller) = contentNode { + let snapshotView = controller.sourceNode.view.snapshotContentTree() + if let snapshotView = snapshotView { + controller.sourceNode.isHidden = true + + self.view.insertSubview(snapshotView, belowSubview: self.contentContainerNode.view) + snapshotView.layer.animateSpring(from: NSValue(cgPoint: localSourceFrame.center), to: NSValue(cgPoint: CGPoint(x: self.contentContainerNode.frame.midX, y: self.contentContainerNode.frame.minY + localSourceFrame.height / 2.0)), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, removeOnCompletion: false) + //snapshotView.layer.animateSpring(from: 1.0 as NSNumber, to: (self.contentContainerNode.frame.width / localSourceFrame.width) as NSNumber, keyPath: "transform.scale", duration: springDuration, initialVelocity: 0.0, damping: springDamping, removeOnCompletion: false) + snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2 * animationDurationFactor, removeOnCompletion: false, completion: { [weak snapshotView] _ in + snapshotView?.removeFromSuperview() + }) + } + } + self.actionsContainerNode.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: localSourceFrame.center.x - self.actionsContainerNode.position.x, y: localSourceFrame.center.y - self.actionsContainerNode.position.y)), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true) self.contentContainerNode.layer.animateSpring(from: NSValue(cgPoint: contentContainerOffset), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true) } } @@ -759,8 +774,10 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi var completedEffect = false var completedContentNode = false var completedActionsNode = false + var targetNode: ASDisplayNode? if let transitionInfo = transitionInfo, let (sourceNode, sourceNodeRect) = transitionInfo.sourceNode() { + targetNode = sourceNode let projectedFrame = convertFrame(sourceNodeRect, from: sourceNode.view, to: self.view) self.originalProjectedContentViewFrame = (projectedFrame, projectedFrame) @@ -837,19 +854,33 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi animateOutToItem = false } - if animateOutToItem, let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame { + if animateOutToItem, let targetNode = targetNode, let originalProjectedContentViewFrame = self.originalProjectedContentViewFrame { let actionsSideInset: CGFloat = 11.0 let localSourceFrame = self.view.convert(CGRect(origin: CGPoint(x: originalProjectedContentViewFrame.1.minX, y: originalProjectedContentViewFrame.1.minY), size: CGSize(width: originalProjectedContentViewFrame.1.width, height: originalProjectedContentViewFrame.1.height)), to: self.scrollNode.view) + if let snapshotView = targetNode.view.snapshotContentTree(unhide: true, keepTransform: true) { + self.view.addSubview(snapshotView) + snapshotView.layer.animatePosition(from: CGPoint(x: self.contentContainerNode.frame.midX, y: self.contentContainerNode.frame.minY + localSourceFrame.height / 2.0), to: localSourceFrame.center, duration: transitionDuration * animationDurationFactor, timingFunction: transitionCurve.timingFunction, removeOnCompletion: false) + snapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2 * animationDurationFactor, removeOnCompletion: false, completion: { _ in + }) + } + self.actionsContainerNode.layer.animatePosition(from: CGPoint(), to: CGPoint(x: localSourceFrame.center.x - self.actionsContainerNode.position.x, y: localSourceFrame.center.y - self.actionsContainerNode.position.y), duration: transitionDuration * animationDurationFactor, timingFunction: transitionCurve.timingFunction, removeOnCompletion: false, additive: true) let contentContainerOffset = CGPoint(x: localSourceFrame.center.x - self.contentContainerNode.frame.center.x, y: localSourceFrame.center.y - self.contentContainerNode.frame.center.y) - self.contentContainerNode.layer.animatePosition(from: CGPoint(), to: contentContainerOffset, duration: transitionDuration * animationDurationFactor, timingFunction: transitionCurve.timingFunction, removeOnCompletion: false, additive: true, completion: { _ in + self.contentContainerNode.layer.animatePosition(from: CGPoint(), to: contentContainerOffset, duration: transitionDuration * animationDurationFactor, timingFunction: transitionCurve.timingFunction, removeOnCompletion: false, additive: true, completion: { [weak self] _ in completedContentNode = true + if let strongSelf = self, let contentNode = strongSelf.contentContainerNode.contentNode, case let .controller(controller) = contentNode { + controller.sourceNode.isHidden = false + } intermediateCompletion() }) } else { - if let snapshotView = controller.view.snapshotContentTree() { + if let contentNode = self.contentContainerNode.contentNode, case let .controller(controller) = contentNode { + controller.sourceNode.isHidden = false + } + + if let snapshotView = controller.view.snapshotContentTree(keepTransform: true) { self.contentContainerNode.view.addSubview(snapshotView) }