Skip to content

Instantly share code, notes, and snippets.

@magnuskahr
Created February 27, 2019 09:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magnuskahr/e28efabd38a1460a531dfae71d50f2b3 to your computer and use it in GitHub Desktop.
Save magnuskahr/e28efabd38a1460a531dfae71d50f2b3 to your computer and use it in GitHub Desktop.
import UIKit
import QuartzCore
class ConfettiView: UIView {
public var colors: [UIColor]!
public var intensity: Float!
private(set) var active: Bool!
override public class var layerClass: Swift.AnyClass {
return CAEmitterLayer.self
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupEmitter()
}
init() {
super.init(frame: .zero)
setupEmitter()
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
guard let superview = superview else {
return
}
NSLayoutConstraint.activate([
topAnchor.constraint(equalTo: superview.topAnchor),
bottomAnchor.constraint(equalTo: superview.bottomAnchor),
leadingAnchor.constraint(equalTo: superview.leadingAnchor),
trailingAnchor.constraint(equalTo: superview.trailingAnchor)
])
layoutIfNeeded()
}
override func layoutSubviews() {
super.layoutSubviews()
guard let emitter = self.layer as? CAEmitterLayer else { return }
emitter.emitterPosition = CGPoint(x: frame.size.width / 2.0, y: -64)
emitter.emitterSize = CGSize(width: frame.size.width, height: 1)
}
func setupEmitter() {
translatesAutoresizingMaskIntoConstraints = false
colors = [UIColor(red:0.93, green:0.30, blue:0.24, alpha:1.00),
UIColor(red:0.95, green:0.60, blue:0.22, alpha:1.00),
UIColor(red:0.97, green:0.80, blue:0.27, alpha:1.00),
UIColor(red:0.47, green:0.84, blue:0.45, alpha:1.00),
UIColor(red:0.46, green:0.78, blue:0.96, alpha:1.00),
UIColor(red:0.17, green:0.49, blue:0.96, alpha:1.00),
UIColor(red:0.33, green:0.36, blue:0.81, alpha:1.00),
UIColor(red:0.93, green:0.27, blue:0.35, alpha:1.00)]
intensity = 0.5
active = false
layer.masksToBounds = true
}
public func startConfetti() {
guard let emitter = self.layer as? CAEmitterLayer else { return }
emitter.emitterShape = CAEmitterLayerEmitterShape.line
var cells = [CAEmitterCell]()
for color in colors {
cells.append(confettiWithColor(color: color, image: #imageLiteral(resourceName: "circle_cut")))
cells.append(confettiWithColor(color: color, image: #imageLiteral(resourceName: "circle")))
cells.append(confettiWithColor(color: color, image: #imageLiteral(resourceName: "line")))
cells.append(confettiWithColor(color: color, image: #imageLiteral(resourceName: "triangle")))
}
emitter.emitterCells = cells
active = true
}
public func stopConfetti() {
guard let emitter = self.layer as? CAEmitterLayer else { return }
emitter.birthRate = 0
active = false
}
private func confettiWithColor(color: UIColor, image: UIImage) -> CAEmitterCell {
let confetti = CAEmitterCell()
confetti.birthRate = 2 * intensity
confetti.lifetime = 14.0 * intensity
confetti.lifetimeRange = 0
confetti.color = color.cgColor
confetti.velocity = CGFloat(350.0 * intensity)
confetti.velocityRange = CGFloat(80.0 * intensity)
confetti.emissionLongitude = CGFloat(Double.pi)
confetti.emissionRange = CGFloat(Double.pi / 2)
confetti.spin = CGFloat(3.5 * intensity)
confetti.spinRange = CGFloat(4.0 * intensity)
confetti.scaleRange = CGFloat(0.5 * intensity)
confetti.scaleSpeed = CGFloat(-0.1 * intensity)
confetti.contents = image.cgImage
return confetti
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment