Lit Fuse Effects can be used to provide uniquely artistic and highly tailorable animation effects that your users will enjoy. These effects can be used to provide eye catching animations to help your users notice a certain area of the screen. These effects might be used in gaming, social media, advertising, or in any app with artistic content.
See example 4 minute video at the below link, and please recognize that it will be higher quality when running on an actual device.
A variety of lit fuse effects are supported where the fuse particles are any sized emoji, or even short text, or a desired image. You can control the size/scale of the emitted cells.
I have exposed control of many cell properties in the visible APIs, which makes these lit fuse effects highly tailorable and uniquely artistic. You can command accelerations, spin, and much more! Many of the cell property parameters have a default value in case you don’t want to specify it. X and Y accelerations are defaulted to zero, and so is spin. Just examine the API for createLitFuseEffectForDesiredRangeOfEmitters. It’s mostly self documenting.
In our terminology below, where we generally say emoji, note that if you chose text, or provided your own image for the cell contents, it’s all still applicable. We anticipate many designs will use emoji.
Very small emoji look like colorful sparks. Large emoji will show as much emoji detail as desired such that the fuse effects are a form of emoji art.
Lit Fuse Effects are generated by placing a trail of emitters on developer specified paths / shapes. The paths can easily be assigned to follow the frame of any UI object! Paths can also follow any combination of circle, line, and rectangle shapes specified.
Emitted cell velocities, cell scales, and cell birth rates are controlled to simulate a burning fuze effect. Developers can control the initial cell velocity, cell scale, and cell birth rate during placement of the fuse. Developers can specify a different velocity, scale, and birth rate while the fuse is burning. And they can specify the ending velocity, scale, and birth rate after burning, thereby simulating a residue (or ash), or no residue or trail left behind at all by specifying an ending scale of zero.
Similarly, you can control X and Y acceleration, spin, and more. Further below, please find the complete parameter list for createLitFuseEffectForDesiredRangeOfEmitters
Note most of the parameters have a sensible default value, zero for spin and X and Y accelerations, etc.
The initial fuse path itself can be either visible or invisible depending on the value for cellInitialScale.
There are 3 stages where you can control the scale of the fuse particles or cells. Size/scale can be specified for the initial fuse path placement, while the fuse is actually burning, and a ending scale for the emitter particles after the fuse has burnt.
If the initial scale is zero, the fuse itself is invisible prior to burning. While burning, the scale needs to be greater than zero to see the burning action. If the ending scale of the emitters after the burn is specified to be non zero, then the burnt path will remain on the screen.
It should be noted that the burnt path that remains on the screen still consists of emitters that constantly emit cells at the last specified birthrate. Those cells can be made to look stationary if the ending cell velocity is zero. There is a subtlety in that the ending cell birthrate multiplied by the ending cell lifetime needs to be greater than 1 for there to be no flicker or strobing effect.
You can specify the ending cell birthrate and the lifetime in the API that creates the lit fuse effect.
Lit fuse effects can be commanded to run continuously, or to run repetively with a time gap between burns, or run as a one shot one time display of the desired animation.
You can specify how quickly the fuse burns by specifying stepsPerFrame. The larger it is, the faster the fuse burns.
Note that you may need to consider whether your app runs on older and slower devices or faster and newer devices, and how many other animations are being drawn to the screen at the same time. Emitter animations can use a lot of CPU and GPU processing. The larger your specified pool is and your chosen fuse parameters may effect performance and produce lag. At first try using these effects with screens that are mostly static. A design that shows a fuse effect, then hides the emitters for a long enough time period to allow all the prior emitted cells to reach the end of their lifetimes may improve fuse performance. Hiding the emitters helps free up resources. Please remember that each emoji cell seen on the screen is there because of an emitter that has a birthrate, and a lifetime specified. Stationary and unchanging emoji are still being born and living lifetimes under the covers, but they just happen to be in the same location. If you want the appearance of stationary and unchanging emoji as the ending state, just make sure the ending birthrate times the ending lifetime is greater than 1. Allow a little overlap.
To create a lit fuse effect, you must create a pool of emitters that will handle the largest numbers of emitters that you intend on using on a path. We suggest anywhere from 50 to 1000 emitters, depending on your path complexity and the desired density.
Below are code snippets that you can use to quickly get the Lit Fuse Effect working in your project.
First import the LitFuseBasicPackage
import LitFuseBasicPackage
Declare a LitFuseBasicViewController object
let litFuse = LitFuseBasicViewController()
If your design could benefit from having multiple lit fuse objects, you can make several of them, like follows. But note you need to call the viewDidLoad for each, call createPoolOfEmitters for each, etc.
let litFuse1 = LitFuseBasicViewController()
let litFuse2 = LitFuseBasicViewController()
let litFuse3 = LitFuseBasicViewController()
let litFuse4 = LitFuseBasicViewController()
Make sure you call the litFuse.viewDidLoad() from the viewDidLoad of your parent view.
Create your pool of emitters right after calling the viewDidLoad. Don’t worry about the default emoji character passed to someEmojiCharacter. You can specify and change it on the fly. But if your design always uses the same emoji character then specify it in the call. Note the emoji character is specified as a string. We take care of converting that string into an image under the covers.
If you are supplying your own image, we have an API that will overwrite the emoji character. We document that below.
Note that it can be so much easier if you already have an object on the screen that has a frame. That frame is a rectangle and it can be passed. In our prototype, we have a UITextView called readMeTextView, and below it’s frame is passed so that the fuse path will actually trace its border.
Note the scaleFactor is an optional parameter. A scaleFactor of 1.0 is right on the border, but if you want a standOff distance so the emitters surround the border with a buffer space, make the scale factor as large as desired, maybe 1.25 or so to get a 25 percent larger fuse path.
For placeEmittersOnSpecifiedRectangle, there is an optional parameter that will cause the fuse to burn counterclockwise instead of clockwise.
Finally, make a call to createLitFuseEffectForDesiredRangeOfEmitters. Note that there are some optional parameters that this example doesn’t use so you have more flexibility if desired. The below code will display the fuse effect continuously.
If you desire to specify a more complex emoji pattern for your fuse effect, you can build an array of emoji. That pattern will get repeated for the specified range of indices. Typically, you will let the indices cover your whole pool.
var arrayOfEmoji = [String]()
arrayOfEmoji.removeAll() // removeAll just in case you already built the array with different emoji already
for _ in 1...4 { arrayOfEmoji.append("🦄") }
for _ in 1...3 { arrayOfEmoji.append("🐝") }
for _ in 1...2 { arrayOfEmoji.append("🐞") }
for _ in 1...1 { arrayOfEmoji.append("🦋") }
litFuse.alternateCellImagesWithGivenArrayOfEmojiOrTextForDesiredRangeOfEmitters(
desiredArrayAsText: arrayOfEmoji,
startIndex: 1,
endIndex: 400)
Instead of using emoji, you can specify a short string of text, such as “Hi” but that’s a feature that hasn’t been thoroughly designed for. It’s one font and one color, white. However, the color can be adjusted by specifying the tint parameter. To get red text for example, specify :
endingTint: .red,
Search this readme for “endingTint” to see how we used it.
If you want to supply your own image, you need to scale that image before you pass it to our API. About 100 pixels across (or less) is a good size to start with. Here is an example call to our API :
Note thisCircleArcFactor as 1 drawns a complete circle. A value of 0.5 would draw an arc for half a circle. The offsetAngleInDegrees would then control at which angle the half circle is shown on the screen.
Using a value of 3 for thisCircleArcFactor would wrap the fuse path around the circle 3 times.
To comb the emitters such that their path radiates from a circle, here’s some sample code :
If you want to stop the combing effect, you need to call these APIs :
litFuse.setFuseEmitterPhases(onlyUseInitialPlacementLogic: false)
// And stop the actual combing.
litFuse.stopCombingTheEmitters(startIndex : 1, endIndex: 400)
We have included an API that lets your design automatically change the emoji at any specified timing period. Note that you can only have one these running at a time. Your emoji changes can be any length, and the emoji go into an array to pass as a parameter. Here’s code :
No license is specified yet for this project. It’s kind of experimental. I’m sharing it with some groups and giving them permission to experiment in order to get feedback. This is my 2nd Swift Package on GitHub and it’s a learning experience for me. This project may be shared under the MIT license at some point in the future. If you have found this repository, you can experiment at will. If you want to release code using it, please email me early on at engineermichigan@gmail.com for approval. If you a small operation that approval should be fine with no considerations. But any large organizations should make an agreement with me. It might make sense to go for patents, build a team, etc. Feel free to contact me about improvements or with requests and with any feedback at all. I take criticism well and I would welcome good suggestions.
If any students or developers want to experiment and make improvements or fork the design, I would consider a collaboration.
Please note that it is possible to overwhelm the GPU and experience lag if you specify very high birth rates (in the thousands) for the cells, or specify a large pool of emitters (again, in the thousands), or you specify long cell lifetimes, or you have many lit fuses displayed at once. Even cell scale may come into play, as the GPU tries to handle the increased workload associated with larger cell images. So you might try to be conservative at first.
With that being said, I think you will easily be able to find reasonable values for those properties in order to achieve some fun and artistic effects. There are potential use cases for gaming, advertising, social media, and any app that presents art to their users.
Initial use cases might choose short time duration effects that are queued at desired events in an app.
If you want to hide a fuse, after it is displayed, just call hideAllEmitters which sets the lifetimes to zero, effectively hiding all the cells.
litFuse.hideAllEmitters()
It might be interesting to try to couple these effects to user swipes on the screen.
And it might be interesting to let developers specify a true path for the emitters to follow instead of specified circles, lines, and rectangles.
There are a couple of APIs that are kind of experimental right now. They couple the alpha speed or scale speed to the specified lifetime of the cells such that the the cells will either fade to invisible, or the scale will shrink to zero over the specified lifetime of the cells.
Here are example calls to these experimantal APIs. The scale speed API is more solid than the alpha speed API.
As time permits, I will try to publish some new packages that depend on LitFuseBasicPackage to coordinate mulitiple lit fuse effects from a Package libary . I’ve already experimented with one that will let you burn fuses at both ends, and it looks very artistic.
— Mike
P.S. If you want to run my driver code, below is a copy and paste of my whole ViewController.swift. Don’t worry about the photos being missing. The code should still build and run, but you won’t have the photos displayed to you like they do in my video link. Note that everything is scaled for an iPad Pro so if you only have an iPhone to experiment with you need to change some values. You can correlate the counter shown on the screen in the lower left corner to find the driving code for each drawn fuse. Just examine touchesBegan and correlate to the variable countOfTouches. If you want to duplicate an effect from the video, just use the same parameters that correlate to the counter shown.
LitFuseBasicPackage
Lit Fuse Effects can be used to provide uniquely artistic and highly tailorable animation effects that your users will enjoy. These effects can be used to provide eye catching animations to help your users notice a certain area of the screen. These effects might be used in gaming, social media, advertising, or in any app with artistic content.
See example 4 minute video at the below link, and please recognize that it will be higher quality when running on an actual device.
https://drive.google.com/file/d/11Lk8fn9NS93S8RDFDb_2iusyy36QO67K/view
A variety of lit fuse effects are supported where the fuse particles are any sized emoji, or even short text, or a desired image. You can control the size/scale of the emitted cells.
I have exposed control of many cell properties in the visible APIs, which makes these lit fuse effects highly tailorable and uniquely artistic. You can command accelerations, spin, and much more! Many of the cell property parameters have a default value in case you don’t want to specify it. X and Y accelerations are defaulted to zero, and so is spin. Just examine the API for createLitFuseEffectForDesiredRangeOfEmitters. It’s mostly self documenting.
In our terminology below, where we generally say emoji, note that if you chose text, or provided your own image for the cell contents, it’s all still applicable. We anticipate many designs will use emoji.
Very small emoji look like colorful sparks. Large emoji will show as much emoji detail as desired such that the fuse effects are a form of emoji art.
Lit Fuse Effects are generated by placing a trail of emitters on developer specified paths / shapes. The paths can easily be assigned to follow the frame of any UI object! Paths can also follow any combination of circle, line, and rectangle shapes specified.
Emitted cell velocities, cell scales, and cell birth rates are controlled to simulate a burning fuze effect. Developers can control the initial cell velocity, cell scale, and cell birth rate during placement of the fuse. Developers can specify a different velocity, scale, and birth rate while the fuse is burning. And they can specify the ending velocity, scale, and birth rate after burning, thereby simulating a residue (or ash), or no residue or trail left behind at all by specifying an ending scale of zero.
Similarly, you can control X and Y acceleration, spin, and more. Further below, please find the complete parameter list for createLitFuseEffectForDesiredRangeOfEmitters Note most of the parameters have a sensible default value, zero for spin and X and Y accelerations, etc.
The initial fuse path itself can be either visible or invisible depending on the value for cellInitialScale.
There are 3 stages where you can control the scale of the fuse particles or cells. Size/scale can be specified for the initial fuse path placement, while the fuse is actually burning, and a ending scale for the emitter particles after the fuse has burnt.
If the initial scale is zero, the fuse itself is invisible prior to burning. While burning, the scale needs to be greater than zero to see the burning action. If the ending scale of the emitters after the burn is specified to be non zero, then the burnt path will remain on the screen.
It should be noted that the burnt path that remains on the screen still consists of emitters that constantly emit cells at the last specified birthrate. Those cells can be made to look stationary if the ending cell velocity is zero. There is a subtlety in that the ending cell birthrate multiplied by the ending cell lifetime needs to be greater than 1 for there to be no flicker or strobing effect.
You can specify the ending cell birthrate and the lifetime in the API that creates the lit fuse effect.
Lit fuse effects can be commanded to run continuously, or to run repetively with a time gap between burns, or run as a one shot one time display of the desired animation.
You can specify how quickly the fuse burns by specifying stepsPerFrame. The larger it is, the faster the fuse burns.
Note that you may need to consider whether your app runs on older and slower devices or faster and newer devices, and how many other animations are being drawn to the screen at the same time. Emitter animations can use a lot of CPU and GPU processing. The larger your specified pool is and your chosen fuse parameters may effect performance and produce lag. At first try using these effects with screens that are mostly static. A design that shows a fuse effect, then hides the emitters for a long enough time period to allow all the prior emitted cells to reach the end of their lifetimes may improve fuse performance. Hiding the emitters helps free up resources. Please remember that each emoji cell seen on the screen is there because of an emitter that has a birthrate, and a lifetime specified. Stationary and unchanging emoji are still being born and living lifetimes under the covers, but they just happen to be in the same location. If you want the appearance of stationary and unchanging emoji as the ending state, just make sure the ending birthrate times the ending lifetime is greater than 1. Allow a little overlap.
Installation with Swift Package Manager
To implement in an Xcode project, select File, Swift Packages, Add Package Dependency, and supply this GitHub link : https://github.com/MichaelKucinski/LitFuseBasicPackage. Then follow the below instructions.
Usage
To create a lit fuse effect, you must create a pool of emitters that will handle the largest numbers of emitters that you intend on using on a path. We suggest anywhere from 50 to 1000 emitters, depending on your path complexity and the desired density.
Below are code snippets that you can use to quickly get the Lit Fuse Effect working in your project.
First import the LitFuseBasicPackage
Declare a LitFuseBasicViewController object
If your design could benefit from having multiple lit fuse objects, you can make several of them, like follows. But note you need to call the viewDidLoad for each, call createPoolOfEmitters for each, etc.
Make sure you call the litFuse.viewDidLoad() from the viewDidLoad of your parent view.
Create your pool of emitters right after calling the viewDidLoad. Don’t worry about the default emoji character passed to someEmojiCharacter. You can specify and change it on the fly. But if your design always uses the same emoji character then specify it in the call. Note the emoji character is specified as a string. We take care of converting that string into an image under the covers.
If you are supplying your own image, we have an API that will overwrite the emoji character. We document that below.
In the viewDidLoad, you will also need to add a sublayer for each element in the pool of emitters.
That completes the initialization needed in viewDidLoad
The rest of the code can get called later, based on any desired event.
To display a lit fuse effect, you may want to set an emoji pattern first.
Next, specify where your emitters are to be placed on the screen. Here is an example that builds two rectangles, and uses them as the fuse path.
Note that it can be so much easier if you already have an object on the screen that has a frame. That frame is a rectangle and it can be passed. In our prototype, we have a UITextView called readMeTextView, and below it’s frame is passed so that the fuse path will actually trace its border.
Note the scaleFactor is an optional parameter. A scaleFactor of 1.0 is right on the border, but if you want a standOff distance so the emitters surround the border with a buffer space, make the scale factor as large as desired, maybe 1.25 or so to get a 25 percent larger fuse path.
For placeEmittersOnSpecifiedRectangle, there is an optional parameter that will cause the fuse to burn counterclockwise instead of clockwise.
public func placeEmittersOnSpecifiedRectangle( thisRectangle : CGRect, startIndex : Int, endIndex : Int, scaleFactor : CGFloat = 1.0, counterClockwiseDesired : Bool = false)
Finally, make a call to createLitFuseEffectForDesiredRangeOfEmitters. Note that there are some optional parameters that this example doesn’t use so you have more flexibility if desired. The below code will display the fuse effect continuously.
At some point, you may want to hide the lit fuse effect. Simply call
Hiding the fuse effect with hideAllEmitters sets all the lifetimes to zero, which should relieve the GPU of any/all fuse processing.
The above should get you going!
You can change the fuse placement whenever you desire, but it may look best to do that while the emitters are hidden.
You can change the emoji whenever you desire, but it may look best to do that while the emitters are hidden.
You can call createLitFuseEffectForDesiredRangeOfEmitters whenever you desire, but it may look best to do that while the emitters are hidden.
Here is the complete parameter list for the API which does the actual fuse burning which includes acceleration, spin, tint color, and more :
If you desire to specify a more complex emoji pattern for your fuse effect, you can build an array of emoji. That pattern will get repeated for the specified range of indices. Typically, you will let the indices cover your whole pool.
Instead of using emoji, you can specify a short string of text, such as “Hi” but that’s a feature that hasn’t been thoroughly designed for. It’s one font and one color, white. However, the color can be adjusted by specifying the tint parameter. To get red text for example, specify :
endingTint: .red,
Search this readme for “endingTint” to see how we used it.
If you want to supply your own image, you need to scale that image before you pass it to our API. About 100 pixels across (or less) is a good size to start with. Here is an example call to our API :
where tempImageToUseWhenChangingCellImages is a UIImage.
If you want to place your fuse path on a line, here is some sample code :
If you want to place your fuse path on a circle, here is some sample code :
Note thisCircleArcFactor as 1 drawns a complete circle. A value of 0.5 would draw an arc for half a circle. The offsetAngleInDegrees would then control at which angle the half circle is shown on the screen.
Using a value of 3 for thisCircleArcFactor would wrap the fuse path around the circle 3 times.
To comb the emitters such that their path radiates from a circle, here’s some sample code :
If you want to stop the combing effect, you need to call these APIs :
We have included an API that lets your design automatically change the emoji at any specified timing period. Note that you can only have one these running at a time. Your emoji changes can be any length, and the emoji go into an array to pass as a parameter. Here’s code :
License
No license is specified yet for this project. It’s kind of experimental. I’m sharing it with some groups and giving them permission to experiment in order to get feedback. This is my 2nd Swift Package on GitHub and it’s a learning experience for me. This project may be shared under the MIT license at some point in the future. If you have found this repository, you can experiment at will. If you want to release code using it, please email me early on at engineermichigan@gmail.com for approval. If you a small operation that approval should be fine with no considerations. But any large organizations should make an agreement with me. It might make sense to go for patents, build a team, etc. Feel free to contact me about improvements or with requests and with any feedback at all. I take criticism well and I would welcome good suggestions.
Email : engineermichigan@gmail.com
If any students or developers want to experiment and make improvements or fork the design, I would consider a collaboration.
Please note that it is possible to overwhelm the GPU and experience lag if you specify very high birth rates (in the thousands) for the cells, or specify a large pool of emitters (again, in the thousands), or you specify long cell lifetimes, or you have many lit fuses displayed at once. Even cell scale may come into play, as the GPU tries to handle the increased workload associated with larger cell images. So you might try to be conservative at first.
With that being said, I think you will easily be able to find reasonable values for those properties in order to achieve some fun and artistic effects. There are potential use cases for gaming, advertising, social media, and any app that presents art to their users.
Initial use cases might choose short time duration effects that are queued at desired events in an app.
If you want to hide a fuse, after it is displayed, just call hideAllEmitters which sets the lifetimes to zero, effectively hiding all the cells.
It might be interesting to try to couple these effects to user swipes on the screen.
And it might be interesting to let developers specify a true path for the emitters to follow instead of specified circles, lines, and rectangles.
There are a couple of APIs that are kind of experimental right now. They couple the alpha speed or scale speed to the specified lifetime of the cells such that the the cells will either fade to invisible, or the scale will shrink to zero over the specified lifetime of the cells.
Here are example calls to these experimantal APIs. The scale speed API is more solid than the alpha speed API.
As time permits, I will try to publish some new packages that depend on LitFuseBasicPackage to coordinate mulitiple lit fuse effects from a Package libary . I’ve already experimented with one that will let you burn fuses at both ends, and it looks very artistic.
— Mike
P.S. If you want to run my driver code, below is a copy and paste of my whole ViewController.swift. Don’t worry about the photos being missing. The code should still build and run, but you won’t have the photos displayed to you like they do in my video link. Note that everything is scaled for an iPad Pro so if you only have an iPhone to experiment with you need to change some values. You can correlate the counter shown on the screen in the lower left corner to find the driving code for each drawn fuse. Just examine touchesBegan and correlate to the variable countOfTouches. If you want to duplicate an effect from the video, just use the same parameters that correlate to the counter shown.