mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Animated emoji improvements
This commit is contained in:
@@ -20,21 +20,21 @@ public final class LottieAnimationComponent: Component {
|
||||
|
||||
public var name: String
|
||||
public var mode: Mode
|
||||
public var colors: [String: UIColor]
|
||||
|
||||
public init(name: String, colors: [String: UIColor], mode: Mode) {
|
||||
public init(name: String, mode: Mode) {
|
||||
self.name = name
|
||||
self.colors = colors
|
||||
self.mode = mode
|
||||
}
|
||||
}
|
||||
|
||||
public let animation: AnimationItem
|
||||
public let colors: [String: UIColor]
|
||||
public let tag: AnyObject?
|
||||
public let size: CGSize?
|
||||
|
||||
public init(animation: AnimationItem, tag: AnyObject? = nil, size: CGSize?) {
|
||||
public init(animation: AnimationItem, colors: [String: UIColor], tag: AnyObject? = nil, size: CGSize?) {
|
||||
self.animation = animation
|
||||
self.colors = colors
|
||||
self.tag = tag
|
||||
self.size = size
|
||||
}
|
||||
@@ -42,6 +42,7 @@ public final class LottieAnimationComponent: Component {
|
||||
public func tagged(_ tag: AnyObject?) -> LottieAnimationComponent {
|
||||
return LottieAnimationComponent(
|
||||
animation: self.animation,
|
||||
colors: self.colors,
|
||||
tag: tag,
|
||||
size: self.size
|
||||
)
|
||||
@@ -51,6 +52,9 @@ public final class LottieAnimationComponent: Component {
|
||||
if lhs.animation != rhs.animation {
|
||||
return false
|
||||
}
|
||||
if lhs.colors != rhs.colors {
|
||||
return false
|
||||
}
|
||||
if lhs.tag !== rhs.tag {
|
||||
return false
|
||||
}
|
||||
@@ -117,6 +121,11 @@ public final class LottieAnimationComponent: Component {
|
||||
|
||||
func update(component: LottieAnimationComponent, availableSize: CGSize, transition: Transition) -> CGSize {
|
||||
var updatePlayback = false
|
||||
var updateColors = false
|
||||
|
||||
if let currentComponent = self.component, currentComponent.colors != component.colors {
|
||||
updateColors = true
|
||||
}
|
||||
|
||||
if self.component?.animation != component.animation {
|
||||
if let animationView = self.animationView {
|
||||
@@ -158,15 +167,7 @@ public final class LottieAnimationComponent: Component {
|
||||
view.backgroundColor = .clear
|
||||
view.isOpaque = false
|
||||
|
||||
if let value = component.animation.colors["__allcolors__"] {
|
||||
for keypath in view.allKeypaths(predicate: { $0.keys.last == "Color" }) {
|
||||
view.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: keypath))
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in component.animation.colors {
|
||||
view.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: "\(key).Color"))
|
||||
}
|
||||
updateColors = true
|
||||
|
||||
self.animationView = view
|
||||
self.addSubview(view)
|
||||
@@ -176,6 +177,23 @@ public final class LottieAnimationComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
self.component = component
|
||||
|
||||
if updateColors, let animationView = self.animationView {
|
||||
if let value = component.colors["__allcolors__"] {
|
||||
for keypath in animationView.allKeypaths(predicate: { $0.keys.last == "Color" }) {
|
||||
animationView.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: keypath))
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in component.colors {
|
||||
if key == "__allcolors__" {
|
||||
continue
|
||||
}
|
||||
animationView.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: "\(key).Color"))
|
||||
}
|
||||
}
|
||||
|
||||
var animationSize = CGSize()
|
||||
if let animationView = self.animationView, let animation = animationView.animation {
|
||||
animationSize = animation.size
|
||||
@@ -187,7 +205,36 @@ public final class LottieAnimationComponent: Component {
|
||||
let size = CGSize(width: min(animationSize.width, availableSize.width), height: min(animationSize.height, availableSize.height))
|
||||
|
||||
if let animationView = self.animationView {
|
||||
animationView.frame = CGRect(origin: CGPoint(x: floor((size.width - animationSize.width) / 2.0), y: floor((size.height - animationSize.height) / 2.0)), size: animationSize)
|
||||
let animationFrame = CGRect(origin: CGPoint(x: floor((size.width - animationSize.width) / 2.0), y: floor((size.height - animationSize.height) / 2.0)), size: animationSize)
|
||||
|
||||
if animationView.frame != animationFrame {
|
||||
if !transition.animation.isImmediate && !animationView.frame.isEmpty && animationView.frame.size != animationFrame.size {
|
||||
let previouosAnimationFrame = animationView.frame
|
||||
|
||||
if let snapshotView = animationView.snapshotView(afterScreenUpdates: false) {
|
||||
snapshotView.frame = previouosAnimationFrame
|
||||
|
||||
animationView.superview?.insertSubview(snapshotView, belowSubview: animationView)
|
||||
|
||||
transition.setPosition(view: snapshotView, position: CGPoint(x: animationFrame.midX, y: animationFrame.midY))
|
||||
snapshotView.bounds = CGRect(origin: CGPoint(), size: animationFrame.size)
|
||||
let scaleFactor = previouosAnimationFrame.width / animationFrame.width
|
||||
transition.animateScale(view: snapshotView, from: scaleFactor, to: 1.0)
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
transition.setPosition(view: animationView, position: CGPoint(x: animationFrame.midX, y: animationFrame.midY))
|
||||
transition.setBounds(view: animationView, bounds: CGRect(origin: CGPoint(), size: animationFrame.size))
|
||||
transition.animateSublayerScale(view: animationView, from: previouosAnimationFrame.width / animationFrame.width, to: 1.0)
|
||||
animationView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.18)
|
||||
} else if animationView.frame.size == animationFrame.size {
|
||||
transition.setFrame(view: animationView, frame: animationFrame)
|
||||
} else {
|
||||
animationView.frame = animationFrame
|
||||
}
|
||||
}
|
||||
|
||||
if updatePlayback {
|
||||
if case .animating = component.animation.mode {
|
||||
|
||||
@@ -261,6 +261,10 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
|
||||
private var isTopPanelExpanded: Bool = false
|
||||
|
||||
public var topPanelComponentView: UIView? {
|
||||
return self.topPanelView?.componentView
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
@@ -774,6 +778,14 @@ public final class PagerComponent<ChildEnvironmentType: Equatable, TopPanelEnvir
|
||||
|
||||
self.component?.isTopPanelExpandedUpdated(self.isTopPanelExpanded, transition)
|
||||
}
|
||||
|
||||
public func collapseTopPanel() {
|
||||
if !self.isTopPanelExpanded {
|
||||
return
|
||||
}
|
||||
|
||||
self.isTopPanelExpandedUpdated(isExpanded: false, transition: Transition(animation: .curve(duration: 0.4, curve: .spring)))
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
|
||||
Reference in New Issue
Block a user