Swiftgram/submodules/PremiumUI/Sources/FasterStarsView.swift
2022-06-11 09:10:01 +04:00

108 lines
3.8 KiB
Swift

import Foundation
import UIKit
import SceneKit
import Display
import AppBundle
final class FasterStarsView: UIView, PhoneDemoDecorationView {
private let sceneView: SCNView
private var particles: SCNNode?
override init(frame: CGRect) {
self.sceneView = SCNView(frame: CGRect(origin: .zero, size: frame.size))
self.sceneView.backgroundColor = .clear
if let url = getAppBundle().url(forResource: "lightspeed", withExtension: "scn") {
self.sceneView.scene = try? SCNScene(url: url, options: nil)
}
self.sceneView.isUserInteractionEnabled = false
self.sceneView.preferredFramesPerSecond = 60
super.init(frame: frame)
self.alpha = 0.0
self.addSubview(self.sceneView)
self.particles = self.sceneView.scene?.rootNode.childNode(withName: "particles", recursively: false)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.particles = nil
}
func setVisible(_ visible: Bool) {
if visible, let particles = self.particles, particles.parent == nil {
self.sceneView.scene?.rootNode.addChildNode(particles)
}
let transition = ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear)
transition.updateAlpha(layer: self.layer, alpha: visible ? 0.4 : 0.0, completion: { [weak self] finished in
if let strongSelf = self, finished && !visible && strongSelf.particles?.parent != nil {
strongSelf.particles?.removeFromParentNode()
}
})
}
private var playing = false
func startAnimation() {
guard !self.playing, let scene = self.sceneView.scene, let node = scene.rootNode.childNode(withName: "particles", recursively: false), let particles = node.particleSystems?.first else {
return
}
self.playing = true
let speedAnimation = CABasicAnimation(keyPath: "speedFactor")
speedAnimation.fromValue = 1.0
speedAnimation.toValue = 1.8
speedAnimation.duration = 0.8
speedAnimation.fillMode = .forwards
particles.addAnimation(speedAnimation, forKey: "speedFactor")
particles.speedFactor = 3.0
let stretchAnimation = CABasicAnimation(keyPath: "stretchFactor")
stretchAnimation.fromValue = 0.05
stretchAnimation.toValue = 0.3
stretchAnimation.duration = 0.8
stretchAnimation.fillMode = .forwards
particles.addAnimation(stretchAnimation, forKey: "stretchFactor")
particles.stretchFactor = 0.3
}
func resetAnimation() {
guard self.playing, let scene = self.sceneView.scene, let node = scene.rootNode.childNode(withName: "particles", recursively: false), let particles = node.particleSystems?.first else {
return
}
self.playing = false
let speedAnimation = CABasicAnimation(keyPath: "speedFactor")
speedAnimation.fromValue = 3.0
speedAnimation.toValue = 1.0
speedAnimation.duration = 0.35
speedAnimation.fillMode = .forwards
particles.addAnimation(speedAnimation, forKey: "speedFactor")
particles.speedFactor = 1.0
let stretchAnimation = CABasicAnimation(keyPath: "stretchFactor")
stretchAnimation.fromValue = 0.3
stretchAnimation.toValue = 0.05
stretchAnimation.duration = 0.35
stretchAnimation.fillMode = .forwards
particles.addAnimation(stretchAnimation, forKey: "stretchFactor")
particles.stretchFactor = 0.05
}
override func layoutSubviews() {
super.layoutSubviews()
self.sceneView.frame = CGRect(origin: .zero, size: frame.size)
}
}