The Spring Festival is coming soon. In big cities, fireworks are still not allowed to cause air pollution. I miss the happy time when I put flowers in my yard when I was a child. But as front-end engineers, this is not a problem for us. Here is how to use JS to set off fireworks in a web page.

Search for “Fireworks” in Codepen to find all kinds of fireworks using JS. The code I’m sharing today is also a reference to one of them.

This minute code after I modify, has been implanted into the “I love nuggets” tadpole pond, as long as send “happy New Year”, “Happy Spring Festival”, you can set off fireworks in the pond.

After reading this post, you’ll be able to write about fireworks on any platform in any language

How does this work?

Let’s create a Canvas

Create a new canvas with the same size as the visual area of the web page, and listen for the resize event in the display area to change the canvas size.

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}

function clearCanvas(){
	context.fillStyle = '#ffffff';
	context.fillRect(0.0,canvas.width, canvas.height);
}

window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
Copy the code

Practice before the fireworks

Fireworks explode from one point and spread out in different radians, so let’s draw a few small dots around a center. It’s kind of like a loading loop. This is actually the first state of fireworks…

function mouseDownHandler(e) {
    var x = e.clientX;
    var y = e.clientY;

    drawFireworks(x,y);
}

function drawFireworks(sx,sy) {
    var count = 10;// The number of fireworks particles
    var radius = 10;// Fireworks around the radius

    for(var i = 0; i<count; i++){var angle = 360/count*i;// Firework particle Angle
        var radians = angle * Math.PI / 180;// Firework particle radians

        var vx = sx+Math.cos(radians) * radius;
        var vy = sy+Math.sin(radians) * radius;

        var size = 2;
        context.beginPath();
        context.arc(vx, vy, size, 0.Math.PI*2.false)
        context.closePath();
        context.fillStyle = "#ff0000"; context.fill(); }}document.addEventListener('mousedown', mouseDownHandler, false);
Copy the code

You know what this code means, right? But now there’s no animation, nothing like fireworks. Don’t worry. We’ll get them moving soon.

move

To move is to continuously draw the radius of the center of a circle from a small value to a large value… So you see, there are two ways to continuously draw, setInterval and requestAnimationFrame, either way.

  1. setInterval

Advantage: it is easy to set the frequency of animation drawing.

var radius = 0;// Radius of the center of the circle
function fire(x,y){
    function tick() {
        drawFireworks(x,y);// Draw the fireworks
        radius++;// The radius keeps getting bigger
    }
    setInterval(tick,30);// Draw every 30 milliseconds
}
Copy the code
  1. requestAnimationFrame

Advantage: drawing frequency is synchronized with browser drawing.

var radius = 0;
function fire(x,y){
    function tick() {
        drawFireworks(x,y);
        radius++;
        requestAnimationFrame(tick);
    }
    tick();
}
Copy the code

Are you feeling it already?

More like fireworks

But the real fireworks certainly won’t be so obedient, to keep the curve and speed, so we have to add some random factors.

var rid;
function fire(x,y){
    createFireworks(x,y);

    function tick() {
        drawFireworks();
        rid=requestAnimationFrame(tick);
    }
    cancelAnimationFrame(rid);
    tick();
}

var particles=[];
function createFireworks(sx,sy){
    particles=[];

    var hue = Math.floor(Math.random()*51) +150;
    var hueVariance = 30;
    var count = 100;

    for(var i = 0; i<count; i++){var p = {};

        var angle = Math.floor(Math.random()*360);
        p.radians = angle * Math.PI / 180;
        p.radius = 0;

        p.sx = sx;
        p.sy = sy;

        p.speed = (Math.random()*5) +4.;

        p.size = Math.floor(Math.random()*3) +1;

        p.hue = Math.floor(Math.random()*((hue+hueVariance)-(hue-hueVariance)))+(hue-hueVariance);
        p.brightness = Math.floor(Math.random()*31) +50;
        p.alpha = (Math.floor(Math.random()*61) +40) /100; particles.push(p); }}function drawFireworks() {
    clearCanvas();

    for(var i = 0; i<particles.length; i++){var p = particles[i];

        p.vx = p.sx+Math.cos(p.radians) * p.radius;
        p.vy = p.sy+Math.sin(p.radians) * p.radius;

        p.radius += 1+p.speed;

        context.beginPath();
        context.arc(p.vx, p.vy, p.size, 0.Math.PI*2.false);
        context.closePath();

        context.fillStyle = 'hsla('+p.hue+'and 100%,+p.brightness+'%,'+100+') '; context.fill(); }}Copy the code

It’s gorgeous, right? Now let’s add a little bit of smoke to it

function tick() {
	// Tips: Note the four new lines of code
	context.globalCompositeOperation = 'destination-out';
	context.fillStyle = 'rgba(0,0,0,'+10/100+') ';
	context.fillRect(0.0,canvas.width,canvas.height);
	context.globalCompositeOperation = 'lighter';
	//tipsend
	drawFireworks();
	rid=requestAnimationFrame(tick);
}
Copy the code

For more realism, we continue to upgrade

Now add some gravity to make the firework particles move slower and slower and slowly fall away

var vx = Math.cos(p.radians) * p.radius;
var vy = Math.sin(p.radians) * p.radius + 0.4;

p.x += vx;
p.y += vy;

p.radius *= 1 - p.speed/100;

p.alpha -= 0.005;
Copy the code

Now the fireworks look is not very fireworks feeling, of course, various parameters you can also be more detailed to add some variables. Draw a firecracker and shoot it into the sky. And finally the fireworks… I’ll leave it up to you to do that.

Set off fireworks on any web page

Create a new bookmark in Chrome, copy the code below, paste it into the url, and save it.

javascript:! (function() {var cdom = document.createElement("canvas"); cdom.id ="myCanvas"; cdom.style.position="fixed"; cdom.style.left ="0"; cdom.style.top ="0"; cdom.style.zIndex=-1;document.body.appendChild(cdom);var canvas = document.getElementById('myCanvas');var context = canvas.getContext('2d');function resizeCanvas() {canvas.width = window.innerWidth; canvas.height =window.innerHeight; }window.addEventListener('resize', resizeCanvas, false); resizeCanvas(); clearCanvas();function clearCanvas(){context.fillStyle = '# 000000'; context.fillRect(0.0,canvas.width, canvas.height); }function mouseDownHandler(e) {var x = e.clientX;vary = e.clientY; fire(x,y); }var rid;function fire(x,y){createFireworks(x,y);function tick() {context.globalCompositeOperation = 'destination-out';    context.fillStyle = 'rgba(0,0,0,'+10/100+') ';    context.fillRect(0.0,canvas.width,canvas.height);    context.globalCompositeOperation = 'lighter'; drawFireworks(); rid=requestAnimationFrame(tick); }cancelAnimationFrame(rid); tick(); }var particles=[];function createFireworks(sx,sy){particles=[];var hue = Math.floor(Math.random()*51) +150;var hueVariance = 30;var count = 100;for(var i = 0; i<count; i++){var p = {};var angle = Math.floor(Math.random()*360); p.radians = angle *Math.PI / 180; p.x = sx; p.y = sy; p.speed = (Math.random()*5) +4.; p.radius = p.speed; p.size =Math.floor(Math.random()*3) +1; p.hue =Math.floor(Math.random()*((hue+hueVariance)-(hue-hueVariance)))+(hue-hueVariance); p.brightness =Math.floor(Math.random()*31) +50; p.alpha = (Math.floor(Math.random()*61) +40) /100; particles.push(p); }}function drawFireworks() {clearCanvas();for(var i = 0; i<particles.length; i++){var p = particles[i];var vx = Math.cos(p.radians) * p.radius;var vy = Math.sin(p.radians) * p.radius + 0.4; p.x += vx; p.y += vy; p.radius *=1 - p.speed/100; p.alpha -=0.005; context.beginPath(); context.arc(p.x, p.y, p.size,0.Math.PI*2.false); context.closePath(); context.fillStyle ='hsla('+p.hue+'and 100%,+p.brightness+'%,'+p.alpha+') '; context.fill(); }}document.addEventListener('mousedown', mouseDownHandler, false); }) ();Copy the code

Download the source code

Wechat search “ezfullStack” follow and reply “Fireworks” to get the source link

Pay attention to a guard

An old programmer playing with big front-end technologies


Recent articles (thanks for your encouragement and support 🌹🌹🌹)

  • 🔥 did a night of animation to better understand Vue3’s Composition Api 891 likes
  • 🔥2020 update: Vue has 1016 likes for the effect of tanking and dragging cards
  • 🔥 recommended favorites, using WebAssembly to protect front-end JS core code combat 102 likes
  • 🔥 no Vue do you remember how to write front end? With JS rewrite 🌜 dark model nuggets home page 49 praise | creator camp
  • 🔥 love the love 🌹, this VSCode plug-in greatly enhance your work mo yu | creator camp 339 great efficiency