Improve birthday effect

This commit is contained in:
Ilya Laktyushin 2024-03-22 14:45:12 +04:00
parent f8196ba656
commit 037380707d
3 changed files with 31 additions and 23 deletions

View File

@ -583,11 +583,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode {
var file: TelegramMediaFile?
switch leftIcon {
case .birthday:
#if DEBUG
file = context.animatedEmojiStickersValue["🔥"]?.first?.file
#else
file = context.animatedEmojiStickersValue["🎂"]?.first?.file
#endif
}
if let file {

View File

@ -28,15 +28,15 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
self.disposable?.dispose()
}
func setup(size: CGSize, birthday: TelegramBirthday) {
self.setupAnimations(size: size, birthday: birthday)
func setup(size: CGSize, birthday: TelegramBirthday, sourceRect: CGRect?) {
self.setupAnimations(size: size, birthday: birthday, sourceRect: sourceRect)
Queue.mainQueue().after(0.1) {
self.view.addSubview(ConfettiView(frame: CGRect(origin: .zero, size: size)))
}
}
private func setupAnimations(size: CGSize, birthday: TelegramBirthday) {
private func setupAnimations(size: CGSize, birthday: TelegramBirthday, sourceRect: CGRect?) {
self.disposable = (combineLatest(
self.context.engine.stickers.loadedStickerPack(reference: .animatedEmojiAnimations, forceActualized: false),
self.context.engine.stickers.loadedStickerPack(reference: .name("FestiveFontEmoji"), forceActualized: false)
@ -84,7 +84,7 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
for file in numberFiles {
let _ = freeMediaFileInteractiveFetched(account: self.context.account, userLocation: .peer(self.context.account.peerId), fileReference: file).startStandalone()
}
self.setupNumberAnimations(size: size, files: numberFiles)
self.setupNumberAnimations(size: size, files: numberFiles, sourceRect: sourceRect)
})
}
@ -108,11 +108,13 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
animationNode.visibility = true
}
private func setupNumberAnimations(size: CGSize, files: [FileMediaReference]) {
private func setupNumberAnimations(size: CGSize, files: [FileMediaReference], sourceRect: CGRect?) {
guard !files.isEmpty else {
return
}
let startY = sourceRect?.midY ?? 475.0
var offset: CGFloat = 0.0
var scaleDelay: Double = 0.0
if files.count > 1 {
@ -138,7 +140,7 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
animationNode.visibility = true
let path = UIBezierPath()
let startPoint = CGPoint(x: 90.0 + offset * 0.7, y: 475.0 + CGFloat.random(in: -20.0 ..< 20.0))
let startPoint = CGPoint(x: 90.0 + offset * 0.7, y: startY + CGFloat.random(in: -20.0 ..< 20.0))
animationNode.position = startPoint
path.move(to: startPoint)
path.addCurve(to: CGPoint(x: 205.0 + offset, y: -90.0), controlPoint1: CGPoint(x: 213.0 + offset * 0.8, y: 380.0 + CGFloat.random(in: -20.0 ..< 20.0)), controlPoint2: CGPoint(x: 206.0 + offset * 0.8, y: 134.0 + CGFloat.random(in: -20.0 ..< 20.0)))
@ -151,6 +153,9 @@ final class PeerInfoBirthdayOverlay: ASDisplayNode {
riseAnimation.beginTime = CACurrentMediaTime() + 0.5
riseAnimation.isRemovedOnCompletion = false
riseAnimation.fillMode = .forwards
riseAnimation.completion = { [weak self] _ in
self?.removeFromSupernode()
}
animationNode.layer.add(riseAnimation, forKey: "position")
offset += 132.0

View File

@ -139,7 +139,7 @@ private final class PeerInfoScreenItemSectionContainerNode: ASDisplayNode {
private let itemContainerNode: ASDisplayNode
private var currentItems: [PeerInfoScreenItem] = []
private var itemNodes: [AnyHashable: PeerInfoScreenItemNode] = [:]
fileprivate var itemNodes: [AnyHashable: PeerInfoScreenItemNode] = [:]
override init() {
self.backgroundNode = ASDisplayNode()
@ -1126,20 +1126,20 @@ private func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoStat
return result
}
private enum InfoSection: Int, CaseIterable {
case groupLocation
case calls
case peerInfo
case peerMembers
}
private func infoItems(data: PeerInfoScreenData?, context: AccountContext, presentationData: PresentationData, interaction: PeerInfoInteraction, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], chatLocation: ChatLocation, isOpenedFromChat: Bool) -> [(AnyHashable, [PeerInfoScreenItem])] {
guard let data = data else {
return []
}
enum Section: Int, CaseIterable {
case groupLocation
case calls
case peerInfo
case peerMembers
}
var items: [Section: [PeerInfoScreenItem]] = [:]
for section in Section.allCases {
var items: [InfoSection: [PeerInfoScreenItem]] = [:]
for section in InfoSection.allCases {
items[section] = []
}
@ -1579,7 +1579,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
}
var result: [(AnyHashable, [PeerInfoScreenItem])] = []
for section in Section.allCases {
for section in InfoSection.allCases {
if let sectionItems = items[section], !sectionItems.isEmpty {
result.append((section, sectionItems))
}
@ -10915,9 +10915,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
if hasBirthdayToday {
Queue.mainQueue().after(0.3) {
var birthdayItemFrame: CGRect?
if let section = self.regularSections[InfoSection.peerInfo] {
if let birthdayItem = section.itemNodes[AnyHashable(400)] {
birthdayItemFrame = birthdayItem.view.convert(birthdayItem.view.bounds, to: self.view)
}
}
let overlayNode = PeerInfoBirthdayOverlay(context: self.context)
overlayNode.frame = CGRect(origin: .zero, size: layout.size)
overlayNode.setup(size: layout.size, birthday: birthday)
overlayNode.setup(size: layout.size, birthday: birthday, sourceRect: birthdayItemFrame)
self.addSubnode(overlayNode)
}
}