Skip to content

Instantly share code, notes, and snippets.

Created January 1, 2015 19:01
Show Gist options
  • Save anonymous/a1d20ccf423b53f3756f to your computer and use it in GitHub Desktop.
Save anonymous/a1d20ccf423b53f3756f to your computer and use it in GitHub Desktop.
Twenty-Fifteen
<canvas id = 'canv'>
</canvas>
<!--Fireworks explode in the vicinity of your mouse !-->
var w = window.innerWidth,
h = window.innerHeight,
mousePos = {
x: 400,
y: 300
},
cnv = document.getElementById('canv'),
ctx = cnv.getContext('2d'),
particles = [],
fireworks = [],
max = 400,
color = 0;
// init
$(document).ready(function() {
cnv.width = w;
cnv.height = h;
setInterval(go, 50);
setInterval(loop, 800 / 50);
});
// update mouse position
$(document).mousemove(function(e) {
e.preventDefault();
mousePos = {
x: e.clientX,
y: e.clientY
};
});
$(document).mousedown(function(e) {
for (var i = 0; i < 5; i++) {
goFrom(Math.random() * w * 2 / 3 + w / 6);
}
});
function go() {
goFrom(mousePos.x);
}
function goFrom(x) {
if (fireworks.length < 10) {
var firework = new Firework(x);
firework.explosionColor = Math.floor(Math.random() * 360 / 10) * 10;
firework.vel.y = Math.random() * -3 - 4;
firework.vel.x = Math.random() * 6 - 3;
firework.size = 8;
firework.shrink = 0.999;
firework.gravity = 0.01;
fireworks.push(firework);
}
}
function loop() {
// update screen size
if (w != window.innerWidth) {
cnv.width = w = window.innerWidth;
}
if (h != window.innerHeight) {
cnv.height = h = window.innerHeight;
}
ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
ctx.fillRect(0, 0, w , h);
var curr_Fireworks = [];
for (var i = 0; i < fireworks.length; i++) {
// update and render
fireworks[i].update();
fireworks[i].render(ctx);
// calculate distance with Pythagoras
var distance = Math.sqrt(Math.pow(mousePos.x - fireworks[i].pos.x, 2) + Math.pow(mousePos.y - fireworks[i].pos.y, 2));
// random chance of 1% if rockets is above the middle
var rnd = fireworks[i].pos.y < (h * 2 / 3) ? (Math.random() * 100 <= 1) : false;
if (fireworks[i].pos.y < h / 5 || fireworks[i].vel.y >= 0 || distance < 50 || rnd) {
fireworks[i].explode();
} else {
curr_Fireworks.push(fireworks[i]);
}
}
fireworks = curr_Fireworks;
var curr_Particles = [];
for (var i = 0; i < particles.length; i++) {
particles[i].update();
// render and save particles that can be rendered
if (particles[i].exists()) {
particles[i].render(ctx);
curr_Particles.push(particles[i]);
}
}
// update array with existing particles
particles = curr_Particles;
while (particles.length > max) {
particles.shift();
}
}
function Particle(pos) {
this.pos = {
x: pos ? pos.x : 0,
y: pos ? pos.y : 0
};
this.vel = {
x: 0,
y: 0
};
this.shrink = .97;
this.size = 2;
this.resistance = 1;
this.gravity = 0;
this.flick = false;
this.alpha = 1;
this.fade = 0;
this.color = 0;
}
Particle.prototype.update = function() {
// resistance
this.vel.x *= this.resistance;
this.vel.y *= this.resistance;
// gravity down
this.vel.y += this.gravity;
// update position based on speed
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
// shrink
this.size *= this.shrink;
// fade out
this.alpha -= this.fade;
};
Particle.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var grd = c.createRadialGradient(x, y, 0.1, x, y, r);
grd.addColorStop(0.1, "rgba(255,255,255," + this.alpha + ")");
grd.addColorStop(0.8, "hsla(" + this.color + ", 100%, 50%, " + this.alpha + ")");
grd.addColorStop(1, "hsla(" + this.color + ", 100%, 50%, 0.1)");
c.fillStyle = grd;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
Particle.prototype.exists = function() {
return this.alpha >= 0.1 && this.size >= 1;
};
function Firework(x) {
Particle.apply(this, [{
x: x,
y:h}]);
this.explosionColor = 0;
}
Firework.prototype = new Particle();
Firework.prototype.constructor = Firework;
Firework.prototype.explode = function() {
var count = Math.random() * 10 + 80;
for (var i = 0; i < count; i++) {
var particle = new Particle(this.pos);
var angle = Math.random() * Math.PI * 2;
// giving a 3D effect by using cosine to have more particles in the middle
var speed = Math.cos(Math.random() * Math.PI / 2) * 15;
particle.vel.x = Math.cos(angle) * speed;
particle.vel.y = Math.sin(angle) * speed;
particle.size = 10;
particle.gravity = 0.2;
particle.resistance = 0.92;
particle.shrink = Math.random() * 0.05 + 0.93;
particle.flick = true;
particle.color = this.explosionColor;
particles.push(particle);
}
};
Firework.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var grd = c.createRadialGradient(x, y, 0.1, x, y, r);
grd.addColorStop(0.1, "rgba(255, 255, 255 ," + this.alpha + ")");
grd.addColorStop(1, "rgba(0, 0, 0, " + this.alpha + ")");
c.fillStyle = grd;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size / 2 + this.size / 2 : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
body {
margin: 0px;
overflow: hidden;
width:100%;
background-image:url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRmOrYzAgSNANBYLV0o7DWJI4j_2lXKXne2od--QNA65fo5hZHzcw'); background-repeat:no-repeat; background-size:100% 100%;
}
canvas{
margin-top:0;
height:100vh;
padding:0;
width:100%;
background:transparent;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment