Fireworks in 5 minutes

About

This project is called "Fireworks" and idea of it came when the Youtube channel was approaching 100 subscribers.
I thought it would be great to celeberate it with... fireworks!
Actually it's quite easy to do it in just 5 minutes using JavaScript and HTML canvas.
One caveat - we need to recall a bit of physics, but it will be fun!

Link to Wikipedia: https://en.wikipedia.org/wiki/Fireworks

Live coding

Here is a live coding session that shows how it can be done.

Duration: 4:37 (coding - 3:40)

Disclaimer: never use this code in production. It was created for fun.

Breakdown

Let's break down the solution and comment on some complex or interesting things.

0:13 - starting with HTML template that will contain a single canvas element.
All the rest will be done using JavaScript.
w and h variables will represent size of the canvas that we will draw on. You can play around with them to fit the canvas to your screen.

0:34 - before we implement actual fireworks we need to understand the physical model behind it.
Imagine that we are talking about one single firework shot (let's call it fireball) and we'll do few assumptions and simplifications:

For every fireball we need to know a couple of input parameters: velocity V and angle α.
When the fireball is shot we assume that it already moves with velocity V (meaning no accelearation from 0 to V).
Take a look at this picture:

Knowing the angle α we can assume that the horizontal velocity is always the same Vx = V·cosα at any point of time t
Vertical velocity is more tricky to calculate. At first the fireball moves up till some point. And then gravity force pushes it down to the ground. We can express vertical velocity as Vy = V·sinα - g·t
When we know the how to calculate velocity at a given point in time t we can taken anti-derivatives of Vx(t) and Vy(t) and get that for time t we have: This should be enough to calculate where the fireball will be located at given point of time t.

Of course it's not a complete introduction into physics so for more details please refer to Wikipedia https://en.wikipedia.org/wiki/Projectile_motion article (by the way, picture you see above is taken from there).

1:11 - now we can implement this physical model.
The heart of the implementation will be a Fireball object that we'll extend with proper functions.
For the start we create a constructor that will have the following parameters:

1:30 - position function is implementing the formulae we discovered before.
It returns both x and y coordinates as single object.
Note that there are a couple of mistakes in implementation (like missed ½) - I discovered them after the video was recorded. But they do not break the logics much - just fireball moves by slightly different curve.

1:51 - nextFrame function is responsible for drawing the fireball on the canvas.
Actual drawing just fills a 5 by 5 square with desired color.
Also it returns false if the fireball has reached its end of life. Notice that for a fireball we are maintaining parameter t that says how much time the fireball is living now.

2:12 - at this point in time we are ready to test our model and do a first shot.
Here we will schedule drawing of a frame using setInterval function. For the first test we can go with a single fireball, but let's make a clever step here and put our fireball into the array and process the array inside setInterval. This will help us in future steps when we need to deal with more than one fireball.
For that purpose we will have a f array that will contain single fireball for now. We initialize it with the following parameters:

Inside setInterval function we first draw a black background and then render all fireballs (well, right now it's only one) by calling nextFrame function.
We can check how it looks in browser to verify our model.

2:44 - usually night sky during fireworks looks bright due to many fireballs are present at the same time. Let's do it as well.
As we are using array to store fireballs - we can easily add more elements to it say every 500 ms.
Probably we want to have different colors for each fireballs. For this we can create a randomColor function that will issue a random color using the following pallete:

Also let's make new shots with random angle as well. Here we need to do some math as well.
Vertical direction is 90 degrees or π/2. We want to have our shots firing mostly vertically with s small deviation, let's say 15 degrees (or π/8) to any side.
This is implemented on line 35 - we'll get an angle between 75 and 105 degrees.
And now adding new fireball is very easy - just add new object to f array! Our overhead on previous step has payed off!
At this point we can do another test in the browser and see the result.

3:21 - probably last remaining bit is to implement fireball's split. In real life when fireball reaches some point it beautifully splits into several smaller pieces.
We can do the same in split function that will create let's say 10 smaller child fireballs.
The logics is quite simple. Imagine we want to fire 10 fireballs from the position of current fireball. So we can generate 10 new Fireball objects with the following initial values:

3:54 - final step is to replace a fireball with its children when a time comes. Technically - it's removing one element from an array and adding 10 more.
For adding all array elements into array we are using JavaScript spread operator

4:04 - doing a final test in a browser to see the results.

This concludes this 100 subscribers special project.
Once again I would like to thank everyone who was participating in channel's life by watching videos, liking them, commenting them and of course subscribing.
If you are not subscribed yet - it's a good time to do it.

Resources

Sources: https://github.com/5minute/firework

See live results:https://jsfiddle.net/5xyr0dnv/