# HTML5 Canvas : Fireworks Effect

Through the previous article, we know the realization principle of the flat throwing motion of an object in HTML5 canvas. Think about the "explosion" of a fireworks. Its effect is like a collection of horizontal throwing movements of multiple fireworks particles. According to this idea, let's try to achieve the fireworks effect.

Because there are too many shortcomings in the conventional drawing method, to manage the movement of each fireworks particle, it is better to encapsulate a fireworks particle into a "particle object", just like modularizing the production process of a product. After modularization, only the materials needed to produce the product are needed.

First, I encapsulate the previous flat cast Code:

``````    function Particle() {
this.x = 100, this.y = 60;
this.g = 1;
this.v = 2;
this.angle = 30;

this.update = function () {
//Uniform linear motion
var vx = Math.cos(this.angle) * this.v;
this.x += vx;

//Uniform acceleration linear motion
var vy = Math.sin(this.angle) * this.v + this.g;
this.y += vy;
}

this.draw = function () {
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, 2 * Math.PI);
ctx.fillStyle = 'hsla(0, 100%, 50%, 1)';
ctx.fill();
}
}
``````

Among them, fireworks particles contain the basic motion parameters, and the drawing and motion of fireworks particles are encapsulated as functions, but these are far from enough.

In real life, fireworks have different colors, and each explosive particle will disperse in different directions at different speeds, because the movement in the air will encounter air resistance. The farther away from the explosion center, the slower the movement speed is. Moreover, it has a life cycle, and will continue to consume energy in the process of lighting. When the last energy is exhausted, it will disappear Lost.

So I enriched the object of fireworks particles:

``````    //Fireworks particle object, parameter hue is the color value of fireworks particle
function Particle(hue) {
//Coordinates of fireworks particle explosion
this.x = 100, this.y = 60;
//Acceleration of gravity
this.g = 1;
//Random movement speed of fireworks particles, fireworks particles will not appear the same distance of movement strange picture
this.v = random(2, 4);
//The movement angle of random fireworks particles, fireworks particles will move to 360 degrees randomly
this.angle = random(0, Math.PI * 2);
//Color value of fireworks particles
this.hue = hue;
//Brightness of fireworks particles
this.brightness = random(50, 80);
//Transparency of fireworks particles
this.alpha = 1;
//The transparency attenuation range of random fireworks particles does not show the strange picture that all fireworks particles disappear at the same time
this.decay = random(0.015, 0.03);

this.update = function () {
//Uniform linear motion
var vx = Math.cos(this.angle) * this.v;
this.x += vx;

//Uniform acceleration linear motion
var vy = Math.sin(this.angle) * this.v + this.g;
this.y += vy;

//After the explosion of fireworks, the velocity of particles in the air decays
this.v *= 0.95;

//Gradually reduce the transparency of fireworks particles
this.alpha -= this.decay;
}

this.draw = function () {
//Draw the grain
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, 2 * Math.PI);
ctx.fillStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')';
ctx.fill();
}
}

function random(min, max) {
return Math.random() * (max - min) + min;
}
``````

As can be seen from the code description above, we can simulate the fireworks control very much!

In this way, I can easily add multiple fireworks particles to the canvas. For example, 30 to 50 fireworks particles can appear when one fireworks explodes:

``````var particlesCount = random(30, 50)
var hue = random(0, 330);
for (var i = 0; i < particlesCount; i++) {
new Particle(hue)；
}
``````

Next, we define an array to uniformly manage these fireworks particles, and use a timer to run the entire animation:

``````    var particles = []
var particlesCount = random(30, 50)

setInterval(function () {
ctx.clearRect(0, 0, 200, 200);

//When there are no fireworks particles, ignite new fireworks
if (particles.length == 0) {
var hue = random(0, 330);
for (var i = 0; i < particlesCount; i++) {
particles.push(new Particle(hue));
}
}

//Continuously update the status of each fireworks particle
for (var i = 0; i < particles.length; i++) {
particles[i].update();
particles[i].draw();

//When a fireworks particle disappears, destroy the fireworks
if (particles[i].alpha <= particles[i].decay) {
particles.splice(i, 1);
}
}
}, 1000 / 60)
``````

The fireworks finally exploded, but the effect was a little bit wrong, as if a little tail was missing.

In the code, we clear the canvas before drawing every frame. If we want to add a small tail, it's very simple. It's not to clear the canvas, but to cover a new layer of transparent sky.

``````The code:
ctx.clearRect(0, 0, 200, 200);

Replace it with:
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
ctx.fillRect(0, 0, 200, 200);
``````

Final code:

``````<html>
<body>
<canvas id="myCanvas" width="200" height="200" style="background-color: black;">
</canvas>
</body>
</html>

<script>
//Prepare canvas
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

function random(min, max) {
return Math.random() * (max - min) + min;
}

//Fireworks particle object, parameter hue is the color value of fireworks particle
function Particle(hue) {
//Coordinates of fireworks particle explosion
this.x = 100, this.y = 60;
//Acceleration of gravity
this.g = 1;
//Random movement speed of fireworks particles, fireworks particles will not appear the same distance of movement strange picture
this.v = random(2, 4);
//The movement angle of random fireworks particles, fireworks particles will move to 360 degrees randomly
this.angle = random(0, Math.PI * 2);
//Color value of fireworks particles
this.hue = hue;
//Brightness of fireworks particles
this.brightness = random(50, 80);
//Transparency of fireworks particles
this.alpha = 1;
//The transparency attenuation range of random fireworks particles does not show the strange picture that all fireworks particles disappear at the same time
this.decay = random(0.015, 0.03);

this.update = function () {
//Uniform linear motion
var vx = Math.cos(this.angle) * this.v;
this.x += vx;

//Uniform acceleration linear motion
var vy = Math.sin(this.angle) * this.v + this.g;
this.y += vy;

//After the explosion of fireworks, the velocity of particles in the air decays
this.v *= 0.95;

//Gradually reduce the transparency of fireworks particles
this.alpha -= this.decay;
}

this.draw = function () {
//Draw the grain
ctx.beginPath();
ctx.arc(this.x, this.y, 2, 0, 2 * Math.PI);
ctx.fillStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')';
ctx.fill();
}
}

var particles = []
var particlesCount = random(30, 50)

setInterval(function () {
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
ctx.fillRect(0, 0, 200, 200);

//When there are no fireworks particles, ignite new fireworks
if (particles.length == 0) {
var hue = random(0, 330);
for (var i = 0; i < particlesCount; i++) {
particles.push(new Particle(hue));
}
}

//Continuously update the status of each fireworks particle
for (var i = 0; i < particles.length; i++) {
particles[i].update();
particles[i].draw();

//When a fireworks particle disappears, destroy the fireworks
if (particles[i].alpha <= particles[i].decay) {
particles.splice(i, 1);
}
}
}, 1000 / 60)

</script>
`````` 