Swift CAEmitterCell CAEmitterLayer Fireworks

Swift CAEmitterCell CAEmitterLayer Fireworks

Created By : Debasis Das (May 2016)

This post is inspired from the Firework Objective C App. The code has been re-written in Swift while removing the slider controls for controlling the fireworks. For the objective C version you can have a look at the below link

https://developer.apple.com/library/mac/samplecode/Fireworks/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009114

Sample Code

//  AppDelegate.swift
//  Swift-CAEmitterCell
//  Created by Debasis Das on 19/05/16.
//  Copyright © 2016 Knowstack. All rights reserved.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate ,NSWindowDelegate{

    @IBOutlet weak var window: NSWindow!
    var rootLayer:CALayer = CALayer()
    var emitterLayer:CAEmitterLayer = CAEmitterLayer()
    @IBOutlet weak var mainView:NSView!

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }

    override func awakeFromNib() {
        print("awakeFromNib")
        self.createFireWorks()
    }
    
    func windowDidResize(notification: NSNotification) {
        self.createFireWorks()
    }
    

    func createFireWorks(){
        self.rootLayer.bounds = self.mainView.bounds
        let color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0)
        rootLayer.backgroundColor = color
        
        let image = NSImage(named: "particle")
        let img:CGImageRef = (image?.CGImageForProposedRect(nil, context: nil, hints: nil))!
        
        print(self.mainView.frame.size.width/2)
        emitterLayer.emitterPosition = CGPointMake(self.mainView.bounds.size.width/2, 20)
        emitterLayer.renderMode = kCAEmitterLayerAdditive
        
        
        let emitterCell = CAEmitterCell()
        emitterCell.emissionLongitude = CGFloat(M_PI / 2)
        emitterCell.emissionLatitude = 0
        emitterCell.lifetime = 2.6
        emitterCell.birthRate = 6
        emitterCell.velocity = 300
        emitterCell.velocityRange = 100
        emitterCell.yAcceleration = 150
        emitterCell.emissionRange = CGFloat(M_PI / 4)
        let newColor = CGColorCreateGenericRGB(0.5, 0.5, 0.5, 0.5);
        emitterCell.color = newColor;
        
        emitterCell.redRange = 0.9;
        emitterCell.greenRange = 0.9;
        emitterCell.blueRange = 0.9;
        emitterCell.name = "base"
        
        let flareCell =  CAEmitterCell()
        flareCell.contents = img;
        flareCell.emissionLongitude = CGFloat(4 * M_PI) / 2;
        flareCell.scale = 0.4;
        flareCell.velocity = 80;
        flareCell.birthRate = 45;
        flareCell.lifetime = 0.5;
        flareCell.yAcceleration = -350;
        flareCell.emissionRange = CGFloat(M_PI / 7);
        flareCell.alphaSpeed = -0.7;
        flareCell.scaleSpeed = -0.1;
        flareCell.scaleRange = 0.1;
        flareCell.beginTime = 0.01;
        flareCell.duration = 1.7;
        
        let fireworkCell = CAEmitterCell()
        
        fireworkCell.contents = img;
        fireworkCell.birthRate = 19999;
        fireworkCell.scale = 0.6;
        fireworkCell.velocity = 130;
        fireworkCell.lifetime = 100;
        fireworkCell.alphaSpeed = -0.2;
        fireworkCell.yAcceleration = -80;
        fireworkCell.beginTime = 1.5;
        fireworkCell.duration = 0.1;
        fireworkCell.emissionRange = 2 * CGFloat(M_PI);
        fireworkCell.scaleSpeed = -0.1;
        fireworkCell.spin = 2;
        
        emitterCell.emitterCells = [flareCell,fireworkCell]
        self.emitterLayer.emitterCells = [emitterCell]
        self.rootLayer.addSublayer(emitterLayer)
        self.mainView.layer = rootLayer
        self.mainView.wantsLayer = true
        self.mainView.needsDisplay = true

    }
}

Swift NSEmitterCell NSEmitterLayer
You can download the project here Swift-CAEmitterCell

Posted in Swift Tagged with: , ,
One comment on “Swift CAEmitterCell CAEmitterLayer Fireworks
  1. Gabe Bryant says:

    Great stuff!

    I had to do some edits so it would run on swift 4, the current version is below.

    Do you have some suggestions for how to easily translate this onto a view of an iPhone app?

    Thanks!

    ——–

    import Cocoa

    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate ,NSWindowDelegate{

    @IBOutlet weak var window: NSWindow!
    var rootLayer:CALayer = CALayer()
    var emitterLayer:CAEmitterLayer = CAEmitterLayer()
    @IBOutlet weak var mainView:NSView!

    func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
    }

    override func awakeFromNib() {
    print(“awakeFromNib”)
    self.createFireWorks()
    }

    func windowDidResize(_ notification: Notification) {
    self.createFireWorks()
    }

    func createFireWorks(){
    self.rootLayer.bounds = self.mainView.bounds
    let color = CGColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
    rootLayer.backgroundColor = color

    let image = NSImage(named: NSImage.Name(rawValue: “particle”))
    let img:CGImage = (image?.cgImage(forProposedRect: nil, context: nil, hints: nil))!

    print(self.mainView.frame.size.width/2)
    emitterLayer.emitterPosition = CGPoint(x: self.mainView.bounds.size.width/2, y: 20)
    emitterLayer.renderMode = kCAEmitterLayerAdditive

    let emitterCell = CAEmitterCell()
    emitterCell.emissionLongitude = CGFloat(Double.pi / 2)
    emitterCell.emissionLatitude = 0
    emitterCell.lifetime = 2.6
    emitterCell.birthRate = 6
    emitterCell.velocity = 300
    emitterCell.velocityRange = 100
    emitterCell.yAcceleration = 150
    emitterCell.emissionRange = CGFloat(Double.pi / 4)
    let newColor = CGColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)
    emitterCell.color = newColor;

    emitterCell.redRange = 0.9
    emitterCell.greenRange = 0.9
    emitterCell.blueRange = 0.9
    emitterCell.name = “base”

    let flareCell = CAEmitterCell()
    flareCell.contents = img
    flareCell.emissionLongitude = CGFloat(4 * Double.pi) / 2
    flareCell.scale = 0.4
    flareCell.velocity = 80
    flareCell.birthRate = 45
    flareCell.lifetime = 0.5
    flareCell.yAcceleration = -350
    flareCell.emissionRange = CGFloat(Double.pi / 7)
    flareCell.alphaSpeed = -0.7
    flareCell.scaleSpeed = -0.1
    flareCell.scaleRange = 0.1
    flareCell.beginTime = 0.01
    flareCell.duration = 1.7

    let fireworkCell = CAEmitterCell()

    fireworkCell.contents = img
    fireworkCell.birthRate = 19999
    fireworkCell.scale = 0.6
    fireworkCell.velocity = 130
    fireworkCell.lifetime = 100
    fireworkCell.alphaSpeed = -0.2
    fireworkCell.yAcceleration = -80
    fireworkCell.beginTime = 1.5
    fireworkCell.duration = 0.1
    fireworkCell.emissionRange = 2 * CGFloat(Double.pi)
    fireworkCell.scaleSpeed = -0.1
    fireworkCell.spin = 2

    emitterCell.emitterCells = [flareCell,fireworkCell]
    self.emitterLayer.emitterCells = [emitterCell]
    self.rootLayer.addSublayer(emitterLayer)
    self.mainView.layer = rootLayer
    self.mainView.wantsLayer = true
    self.mainView.needsDisplay = true

    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*