iosswiftcaemitterlayerfireworks

How do I set fire to a UIView in Swift?


How do I produce an animation that simulates the burning effect of fire consuming an UIView from top to bottom in Swift?

I found Fireworks, an app that allows users to tweak and try out different settings of CAEmitterLayer with instant results. The effects are great for applying to a whole screen but how would I use it for my purpose - where the UIView must disappear as the fire consumes it from one end to the other?

Is there some tutorial on consuming UIViews with fire using the particle emitter anywhere? I know that I’m supposed to show some code but anything I put here would be irrelevant. I’ve also exhausted my search engine looking for something similar. That’s how I found the Fireworks app actually.

This seems to be a use case that shouldn't be uncommon.


Solution

  • I haven't done much with CAEmitterLayer, so I decided to try my hand at this.

    I created a project that does this an posted it on Github. It uses the approach in this Youtube video as a starting point. You can download it here:

    FireEmitter project

    Here is a small thumbnail of what it looks like:

    The project includes a custom subclass of UIView called BurnItDownView

    The BurnItDownView is meant to contain other views.

    It has one public method, burnItDown(). That triggers the animation.

    There are multiple parts to the animation:

    1. A CAEmitterLayer set up to simulate flames burning off a flat surface:
    2. An animation that lowers the emitter layer from the top of the view to the bottom,
    3. A CAGradientView applied as a mask to the view that starts ot fully opaque (with colors of [.clear, .white, .white] and locations of [-0.5, 0, 1] (where the clear color is above the top of the view) and animates the locations property of the gradient view to mask away the view contents from top to bottom. (Animating the locations property to [0, 0, 0], so the entire gradient layer is filled with clear color, fully masking the view's layer.)
    4. Once the view is fully masked, it starts lowering the "birthRate" of the emitter layer in steps until the birth rate is 0. It then holds this step for 2 seconds until all the flame particles have animated away.
    5. Once the flame is fully "extinguised", it resets the locations array to the original value of [-0.5, 0, 1]. This causes an "implicit animation" so the view animates back from the bottom, but quickly
    6. Finally, it resets the emitter layer and emitter cells back to newly a newly created emitter layer and emitter cell to get it ready for the next pass of the animation. (I couldn't figure out how to restore the emitter back to its original state. It was simpler to just create new ones.) It also invokes an Optional completion handler passed to the burnItDown() method. (The app's view controller uses the closure to re-enable the "Burn it down" button.