JSFiddle - React, Tailwind, and code Playground
by jcubed111
HTML
<canvas id='main' width=500 height=500></canvas>
CSS
body{
margin: 0;
}
canvas{
background: #000;
}
JavaScript
function rand(min, max) {
return Math.random() * (max - min) + min;
}
function randColor(colors) {
const i = Math.random() * (colors.length - 1);
return colors[~~i].lerp(colors[~~i+1], Math.random());
}
let canvas = document.getElementById('main');
let ctx = canvas.getContext('2d');
let particles = [];
class Vec{
constructor(x, y, z = 0, w = 1) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
plus(b, factor = 1, wFactor = factor) {
return new this.constructor(this.x + b.x * factor, this.y + b.y * factor, this.z + b.z * factor, this.w + b.w * wFactor);
}
times(factor, wFactor = factor) {
return new this.constructor(this.x * factor, this.y * factor, this.z * factor, this.w * wFactor);
}
minus(b, factor = 1, wFactor = factor) {
return this.plus(b, -factor, -wFactor);
}
lerp(other, factor) {
return this.times(1 - factor).plus(other, factor);
}
}
class Color extends Vec{
atAlpha(a) {
return new Color(this.x, this.y, this.z, this.w * a);
}
toString() {
return `rgba(${~~this.x}, ${~~this.y}, ${~~this.z}, ${this.w})`;
}
}
class Particle{
constructor(pos, vel, color, life) {
this.pos = pos;
this.vel = vel;
this.color = color;
this.life = life;
this.maxLife = life;
}
render() {
const alpha = Math.pow(this.life / this.maxLife, 0.5);
ctx.fillStyle = this.color.atAlpha(alpha).toString();
ctx.fillRect(~~this.pos.x, ~~this.pos.y, 2, 2);
}
step(dt) {
this.pos = this.pos.plus(this.vel, dt);
this.vel.y += 20000 * dt*dt;
this.life -= dt;
}
}
function makeParticles(pos, radius, colors) {
for(let x = -radius; x < radius; x++) {
for(let y = -radius; y < radius; y++) {
if(x*x + y*y >= radius * radius) continue;
//if(x*x + y*y < 2) continue;
let dp = new Vec(
x*rand(0.5, 1.5)+rand(-1,...