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
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.
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:
V
and angle α
.
V
(meaning no accelearation from 0
to V
).
α
we can assume that the horizontal velocity is always the same Vx = V·cosα
at any point of time t
Vy = V·sinα - g·t
t
we can taken anti-derivatives of Vx(t)
and Vy(t)
and get that for time t
we have:
x(t) = t·V·cosα
y(t) = t·V·sinα - ½g·t²
t
.
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:
x0
and y0
- initial coordinates of a fireballv
- velocityangle
- the angle at which the fireball is shot. It starts from 3 o'clock and goes conter-clockwise (vertical is 90 degrees or π/2
)ttl
- how long the fireball should be alive (TTL stands for "time to live")color
- the color in which the fireball will be displayed
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:
h
is canvas height, then I found out out that h/5
might be a good value for velocityπ/3
. Remember that in most programming languages trigonometric functions normally work with radians and not with degrees!setInterval
is called every 20 ms and nextFrame
increases t
by 0.05
. That means that during 1 second there will be 50 frames drawn, each of them will increase t
by 0.05
. So during one second t
will be increased by 50 * 0.05 = 0.25
. So the actual fireball will be alive during 6/0.25 = 24 seconds
setInterval
function we first draw a black background and then render all fireballs (well, right now it's only one) by calling nextFrame
function.
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:
π/2
. We want to have our shots firing mostly vertically with s small deviation, let's say 15 degrees (or π/8
) to any side.
f
array! Our overhead on previous step has payed off!
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:
i
-th child will have angle 360/10 * i = 36 * i = i * 2*π/10
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.
Sources: https://github.com/5minute/firework
See live results:https://jsfiddle.net/5xyr0dnv/