Firework effect.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Fireworks</title>
<style type="text/css">
/* basic browser reset */
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
</style>
</head>
<body data-rsssl=1>
<canvas></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
// VARIABLEZ
// play with them
var c = document.querySelector('canvas'),
ctx = c.getContext('2d'),
width = c.width = window.innerWidth,
height = c.height = window.innerHeight,
n_stars = 150, //num of stars
stars = [], //array to store generated stars
twinkleFactor = .4, //how much stars 'twinkle'
maxStarRadius = 3,
fw1, fw2, //firework objects
minStrength = 1.5, //lowest firework power
maxStrength = 7, //highest firework power
minTrails = 7, //min particles
maxTrails = 30, //max particles
particleRadius = 2,
trailLength = 15, //particle trail length
delay = .5, // number of LIFEs between explosions
LIFE = 150, //life time of firework
g = 5e-2, //strength of gravity
D = 1e-3; //strength of drag (air resistance)
// Particle Class
var Particle = function(x, y, vx, vy, ax, ay, colour) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.ax = ax;
this.ay = ay;
this.life = LIFE; //only here for opacity in .draw() method
this.path = [];
this.colour = colour;
this.r = particleRadius;
this.update = function() {
this.life--;
// add point to path but if full, remove a point first
if (this.path.length >= trailLength) this.path.shift();
this.path.push([this.x, this.y])
// update speed n position n stuff
this.vy += this.ay;
this.vx += this.ax;
this.x += this.vx;
this.y += this.vy;
}
this.draw = function() {
var opacity = ~~(this.life * 100 / LIFE) / 100;
// tail
ctx.fillStyle = 'rgba(' + this.colour + (opacity * 0.4) + ')';
if (this.life > LIFE * 0.95) ctx.fillStyle = '#fff';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(this.x - this.r, this.y);
var i = this.path.length - 1;
ctx.lineTo(this.path[0][0], this.path[0][1]);
ctx.lineTo(this.x + this.r, this.y);
ctx.closePath();
ctx.fill();
// main dot
ctx.fillStyle = 'rgba(' + this.colour + opacity + ')';
if (this.life > LIFE * 0.95) ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.arc(~~this.x, ~~this.y, this.r, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
}
// Firework class
var Firework = function() {
this.x = width * (Math.random() * 0.8 + 0.1); // from 0.1-0.9 widths
this.y = height * (Math.random() * 0.8 + 0.1); // from 0.1-0.9 heights
this.strength = Math.random() * (maxStrength - minStrength) + minStrength;
this.colour = ~~(Math.random() * 255) + ',' +
~~(Math.random() * 255) + ',' +
~~(Math.random() * 255) + ',';
this.life = 0;
this.particles = (function(x, y, strength, colour) {
var p = [];
var n = ~~(Math.random() * (maxTrails - minTrails)) + minTrails;
var ay = g;
for (var i = n; i--;) {
var ax = D;
var angle = i * Math.PI * 2 / n;
if (angle < Math.PI) ax *= -1;
var vx = strength * Math.sin(angle);
var vy = strength * Math.cos(angle);
p.push(new Particle(x, y, vx, vy, ax, ay, colour));
}
return p;
})(this.x, this.y, this.strength, this.colour);
this.update = function() {
this.life++;
if (this.life < 0) return; //allows life to be delayed
for (var i = this.particles.length; i--;) {
this.particles[i].update();
this.particles[i].draw();
//wasn't bothered to make an extra draw function for firework class
}
}
};
var Star = function() {
this.x = Math.random() * width;
this.y = Math.random() * height;
this.r = Math.random() * maxStarRadius;
this.b = ~~(Math.random() * 100) / 100;
}
Star.prototype.draw = function() {
this.b += twinkleFactor * (Math.random() - .5);
ctx.fillStyle = 'rgba(255,255,255,' + this.b + ')';
ctx.beginPath();
ctx.arc(~~this.x, ~~this.y, this.r, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
function createStars() {
for (var i = n_stars; i--;) stars.push(new Star);
}
function main() {
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, width, height);
for (var i = n_stars; i--;) stars[i].draw();
fw1.update();
fw2.update();
if (fw1.life == LIFE * delay) fw2 = new Firework;
if (fw2.life == LIFE * delay) fw1 = new Firework;
window.requestAnimationFrame(main);
}
function init() {
fw1 = new Firework;
fw2 = new Firework;
fw2.life = -LIFE * delay;
createStars();
main();
}
init();
});
</script>
</body>
</html>