/*import Foundation import UIKit import Display private let purple = UIColor(rgb: 0x3252ef) private let pink = UIColor(rgb: 0xe4436c) private let latePurple = UIColor(rgb: 0x974aa9) private let latePink = UIColor(rgb: 0xf0436c) public final class AnimatedCountView: UIView { let countLabel = AnimatedCountLabel() // let titleLabel = UILabel() let subtitleLabel = UILabel() private let foregroundView = UIView() private let foregroundGradientLayer = CAGradientLayer() private let maskingView = UIView() override init(frame: CGRect = .zero) { super.init(frame: frame) self.foregroundGradientLayer.type = .radial self.foregroundGradientLayer.colors = [pink.cgColor, purple.cgColor, purple.cgColor] self.foregroundGradientLayer.locations = [0.0, 0.85, 1.0] self.foregroundGradientLayer.startPoint = CGPoint(x: 1.0, y: 0.0) self.foregroundGradientLayer.endPoint = CGPoint(x: 0.0, y: 1.0) self.foregroundView.mask = self.maskingView self.foregroundView.layer.addSublayer(self.foregroundGradientLayer) self.addSubview(self.foregroundView) // self.addSubview(self.titleLabel) self.addSubview(self.subtitleLabel) self.maskingView.addSubview(countLabel) countLabel.clipsToBounds = false subtitleLabel.textAlignment = .center // self.backgroundColor = UIColor.white.withAlphaComponent(0.1) } override public func layoutSubviews() { super.layoutSubviews() self.foregroundView.frame = CGRect(origin: CGPoint.zero, size: bounds.size)// .insetBy(dx: -40, dy: -40) self.foregroundGradientLayer.frame = CGRect(origin: .zero, size: bounds.size).insetBy(dx: -60, dy: -60) self.maskingView.frame = CGRect(origin: .zero, size: bounds.size) countLabel.frame = CGRect(origin: .zero, size: bounds.size) subtitleLabel.frame = .init(x: bounds.midX - subtitleLabel.intrinsicContentSize.width / 2 - 10, y: subtitleLabel.text == "No viewers" ? bounds.midY - 10 : bounds.height - 6, width: subtitleLabel.intrinsicContentSize.width + 20, height: 20) } func update(countString: String, subtitle: String) { self.setupGradientAnimations() let text: String = countString// presentationStringsFormattedNumber(Int32(count), ",") // self.titleNode.attributedText = NSAttributedString(string: "", font: Font.with(size: 23.0, design: .round, weight: .semibold, traits: []), textColor: .white) // let titleSize = self.titleNode.updateLayout(size) // self.titleNode.frame = CGRect(x: floor((size.width - titleSize.width) / 2.0), y: 48.0, width: titleSize.width, height: titleSize.height) if CGFloat(text.count * 40) < bounds.width - 32 { self.countLabel.attributedText = NSAttributedString(string: text, font: Font.with(size: 60.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: .white) } else { self.countLabel.attributedText = NSAttributedString(string: text, font: Font.with(size: 54.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: .white) } // var timerSize = self.timerNode.updateLayout(CGSize(width: size.width + 100.0, height: size.height)) // if timerSize.width > size.width - 32.0 { // self.timerNode.attributedText = NSAttributedString(string: text, font: Font.with(size: 60.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: .white) // timerSize = self.timerNode.updateLayout(CGSize(width: size.width + 100.0, height: size.height)) // } // self.timerNode.frame = CGRect(x: floor((size.width - timerSize.width) / 2.0), y: 78.0, width: timerSize.width, height: timerSize.height) self.subtitleLabel.attributedText = NSAttributedString(string: subtitle, font: Font.with(size: 16.0, design: .round, weight: .semibold, traits: []), textColor: .white) self.subtitleLabel.isHidden = subtitle.isEmpty // let subtitleSize = self.subtitleNode.updateLayout(size) // self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: subtitleSize.width, height: subtitleSize.height) // self.foregroundView.frame = CGRect(origin: CGPoint(), size: size) // self.setNeedsLayout() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupGradientAnimations() { if let _ = self.foregroundGradientLayer.animation(forKey: "movement") { } else { let previousValue = self.foregroundGradientLayer.startPoint let newValue = CGPoint(x: CGFloat.random(in: 0.65 ..< 0.85), y: CGFloat.random(in: 0.1 ..< 0.45)) self.foregroundGradientLayer.startPoint = newValue CATransaction.begin() let animation = CABasicAnimation(keyPath: "startPoint") animation.duration = Double.random(in: 0.8 ..< 1.4) animation.fromValue = previousValue animation.toValue = newValue CATransaction.setCompletionBlock { [weak self] in // if let isCurrentlyInHierarchy = self?.isCurrentlyInHierarchy, isCurrentlyInHierarchy { self?.setupGradientAnimations() // } } self.foregroundGradientLayer.add(animation, forKey: "movement") CATransaction.commit() } } } class AnimatedCharLayer: CATextLayer { var text: String? { get { self.string as? String ?? (self.string as? NSAttributedString)?.string } set { self.string = newValue } } var attributedText: NSAttributedString? { get { self.string as? NSAttributedString //?? (self.string as? String).map { NSAttributed.init } set { self.string = newValue } } var layer: CALayer { self } override init() { super.init() self.contentsScale = UIScreen.main.scale } override init(layer: Any) { super.init(layer: layer) self.contentsScale = UIScreen.main.scale } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class AnimatedCountLabel: UILabel { override var text: String? { get { chars.reduce("") { $0 + ($1.text ?? "") } } set { update(with: newValue ?? "") } } override var attributedText: NSAttributedString? { get { let string = NSMutableAttributedString() for char in chars { string.append(char.attributedText ?? NSAttributedString()) } return string } set { udpateAttributed(with: newValue ?? NSAttributedString()) } } private var chars = [AnimatedCharLayer]() private let containerView = UIView() override init(frame: CGRect = .zero) { super.init(frame: frame) containerView.clipsToBounds = false addSubview(containerView) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } var itemWidth: CGFloat { 36 } var commaWidth: CGFloat { 8 } var interItemSpacing: CGFloat { 0 } private func offsetForChar(at index: Int, within characters: [NSAttributedString]? = nil) -> CGFloat { if let characters { return characters[0..