Building a Fireworks Animation with HTML5 Canvas and JavaScript
Fireworks are a captivating visual spectacle, and you can bring this excitement to your website by creating a dynamic fireworks animation using HTML5 Canvas and JavaScript. In this tutorial, we’ll explore a step-by-step guide to understand and implement the provided code.
Before we get start you can download the project files below:
Demo
Take a look at what the code creates:
Requirements and prerequisites
The code is intended to be run in a web browser. Open the HTML file in a modern web browser such as Google Chrome, Mozilla Firefox, Safari, or Microsoft Edge.
Make sure that JavaScript is enabled in your web browser, as the entire animation is implemented in JavaScript.
The code relies on the HTML5 Canvas API. Ensure that the browser supports HTML5 and has Canvas API support.
The code can be hosted on a web server or executed locally. If you are running it locally, you may encounter security restrictions (CORS issues) when loading external scripts or assets. Hosting it on a server can help avoid such issues.
HTML Setup
Firstly, set up your HTML file by creating a canvas element where the fireworks will come to life.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
}
</style>
<title>Fireworks Animation</title>
</head>
<body>
<canvas id="fireworksCanvas"></canvas>
<script src="library.js"></script>
<script src="fireworks.js"></script>
</body>
</html>
JavaScript Setup
The code below creates objects the different parts of the fireworks such as the particle and fireworks objects. In the example files, this code is within the "library.js" file.
//fireworks object to create a fireworks
const fireworksObject = function(x,y,target){
this.x =x;
this.y=y;
this.direction=null;
this.target={x:target.x,y:target.y}
//number of particles to release on explosion;
this.count=20;
this.speed=10;
this.particle_life=[10,30];
this.particle_speed=[1,5];
this.segments=[];
this.segment_limit=5;
this.init()
}
fireworksObject.prototype={
init:function(){
this.segments.push({x:this.x,y:this.y});
var dx=this.target.x-this.x;
var dy=this.target.y-this.y;
var magnitude=Math.sqrt(dx*dx+dy*dy);
//normalized direction
var nx=dx/magnitude;
var ny=dy/magnitude;
this.direction={x:nx,y:ny};
},
explode:function(fireworks,particles,canvas){
var index=fireworks.findIndex(item =>item ==this);
fireworks.splice(index,1);
var i=0;
while(i<this.count){
var x0=Math.random(0,1)*canvas.width;
var y0=Math.random(0,1)*canvas.height;
var life=Math.random(0,1)*this.particle_life[1]+this.particle_life[0];
var speed=Math.random(0,1)*this.particle_speed[1]+this.particle_speed[0];
particles.push(create_particle(this.x,this.y,life,speed,{x:x0,y:y0}));
i++;
}
delete(this);
},
move:function(){
this.x+=this.speed*this.direction.x;
this.y+=this.speed*this.direction.y;
}
,
update:function(gl,fireworks,particles,canvas){
//move the fireworks
this.move();
//drawing the fire works;
gl.beginPath();
gl.strokeStyle=`hsl(${Math.random() * 5000}, 100%, 50%)`;
gl.lineWidth=Math.random(0,1)*2+1;
var last_pos=this.segments[this.segments.length-1];
gl.moveTo(last_pos.x, last_pos.y);
gl.lineTo(this.x,this.y);
gl.stroke();
gl.closePath();
this.segments.push({x:this.x,y:this.y})
if(this.segments.length>=this.segment_limit){
this.segments.splice(0,1);
}
var dx=this.target.x-this.x;
var dy=this.target.y-this.y;
var distance=Math.sqrt(dx*dx+dy*dy)
if(distance<=10){
this.explode(fireworks,particles,canvas);
}
}
}
function create_fireworks(x,y,target){
return new fireworksObject(x,y,target);
}
//particle object to create particles from the fireworks
const particle = function(x,y,life,speed,target){
this.x=x;
this.y=y;
this.life=life;
this.decay=1;
this.direction=null;
this.target={x:target.x,y:target.y};
this.speed=speed;
this.gravity=2;
this.segments=[];
this.segment_limit=5;
this.init();
}
particle.prototype={
init:function(){
this.segments.push({x:this.x,y:this.y});
var dx=this.target.x-this.x;
var dy<