var canvas = document.createElement('canvas'), context = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; document.body.appendChild(canvas); Particle.prototype.getPoint = function () { return { x: (this.current.radius * Math.cos(this.current.angle * Math.PI / 180)) + this.current.x - (this.current.w/2), y: (this.current.radius * Math.sin(this.current.angle * Math.PI / 180)) + this.current.y - (this.current.h/2) }; } var particles = []; for (var i = 0; i < 1000; i++) { particles.push(new Particle({ x: window.innerWidth/2, y: window.innerHeight/2, w: Particle.prototype.random(1,3), h: Particle.prototype.random(1,3), radius: Particle.prototype.random(Math.random() < .4 ? 1 : 20,75), angle: Particle.prototype.random(0, 360), color: 'rgb(' + [Math.floor(Math.random() * 255),Math.floor(Math.random() * 255),Math.floor(Math.random() * 255)].join(',') + ')', minAngleDecay: Particle.prototype.random(10, 600) })); } var lastFrame = 0, fps = 60, start = Date.now(); function draw() { requestAnimationFrame(draw); var frame = Math.floor((Date.now() - start) / (1000/fps)); if (lastFrame === frame) { return; } context.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(function (particle) { if (Math.random() > .90 && (!particle.decay.angle || Math.floor(Math.abs(particle.decay.angle)) < particle.value.minAngleDecay)) { particle.decay.angle = particle.random(particle.value.minAngleDecay, 200); } if (Math.random() > .90 && (!particle.decay.radius || Math.floor(Math.abs(particle.decay.radius)) < 20)) { particle.decay.radius = particle.value.radius - particle.current.radius; } for (var i = 0; i < frame - lastFrame; i++) { particle.updateDecay(.97); } var point = particle.getPoint(); context.fillStyle = particle.value.color; context.beginPath(); context.arc(point.x, point.y, particle.current.w/2, 0, 2 * Math.PI, false); context.fill(); }); lastFrame = frame; } draw(); var mouseDownTime; window.addEventListener('mousedown', function () { mouseDownTime = new Date(); }); window.addEventListener('mouseup', function () { particles.forEach(function (particle) { particle.decay.radius = particle.random(0, new Date() - mouseDownTime); }); }); window.addEventListener('mousemove', function (event) { particles.forEach(function (particle) { particle.decay.x = event.x - particle.current.x; particle.decay.y = event.y - particle.current.y; }) });