Fire

by Scott Kaye

HTML

<canvas id="c"></canvas>

CSS

canvas {
	position: fixed;
	bottom: 0;
	left: 50%;
	transform: translateX(-50%);
}

body {
	background: #000;
	overflow: hidden;
	height: 100vh;
}

JavaScript

console.clear();
let canvas = document.querySelector("#c");
let context = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = 100;

function createParticle() {
	return {
		x: Math.random() * canvas.width,
		y: canvas.height + Math.random() * 20,
		vx: (Math.random() - 0.5) / 2,
		vy: (Math.random() - 1) / 2,
		life: Math.random(),
		size: Math.random() + 3 * 5
	};
}

let particles = Array(1000).fill().map(createParticle);

function draw() {
	context.fillStyle = "rgba(0,0,0,0.1)";
	context.fillRect(0, 0, canvas.width, canvas.height);
	
	let i = particles.length;
	while(--i) {
		let p = particles[i];
		p.life -= 0.005;
		p.size = Math.abs(p.size - p.life / 10);
		
		if (p.life <= 0) {
			particles[i] = createParticle();
		}
		
		p.vx += (Math.random() - 0.5) / 20;
		
		p.x += p.vx;
		p.y += p.vy;
		
		let r = 255;
		let g = (p.life * 255 * 2) | 0;
		let b = (p.life * 255 * 0.75) | 0;
		let a = p.life;
		
		context.fillStyle = `rgba(${r},${g},${b},${a})`;
		
		let spread = p.size * 2;
		
		context.beginPath();
		context.fillRect(p.x + (Math.random() - 0.5) * spread, p.y + (Math.random() - 0.5) * spread, p.size, p.size);
		context.arc(p.x, p.y, p.size, 0, 2 * Math.PI);
		context.fill();
	}

	window.requestAnimationFrame(draw);
}

draw();