xxxxxxxxxx
143
// Firework-like visual
// Object Firework contains object Particles
// terms: x, vx, ax -> position, velocity, acceleration on x axis
let firework;
function setup() {
let cvs = createCanvas(700, 500); // Sets default size and ratio.
cvs.canvas.style.width='100%'; // 100% width of available space
cvs.canvas.style.height='auto';
background(10);
colorMode(HSB,100);
frameRate(55);
firework = new Firework();
}
function draw() {
background('rgba(0,0,0, 0.05)');
firework.update();
}
class Firework {
constructor() {
this.init();
}
init() {
this.size = 5;
this.x = width/2+random(-150,150);
this.y = height;
this.vx = random(-3,3);
this.vy = 0;
this.ay = random(-1.6,-1.4); // decides maximum height reached
this.px = this.x;
this.py = this.y;
this.particleCount = 300; // number of colored particles
this.particles = [];
this.loadParticles(); // create particles
this.exploded = false;
this.particleEnded = 0;
}
move() {
this.px = this.x;
this.py = this.y;
this.x += random(-2,2);
this.y += this.vy;
}
accelerate() {
this.ay += 0.02;
this.vy += this.ay;
this.vy *= 0.85;
}
update() {
if (this.exploded) {
for (let i=0;i<this.particleCount;i++) { // particle starts moving
this.particles[i].update(); // when the explosion occurs
}
if (this.particleCount==this.particleEnded) { // if all particle died
this.init(); // restart
}
} else {
this.accelerate();
this.move();
this.draw();
if (this.vy>0) {this.explode();} // when starts falling
}
}
draw() {
push();
strokeWeight(this.size);
stroke(0,0,95);
line(this.x,this.y,this.px,this.py);
pop();
}
loadParticles() {
let colorBase = random(100); // color range is set, so need color base
for (let i=0;i<this.particleCount;i++) {
let color = (colorBase+i%30)%100; // color range
append(this.particles,new Particle(this,color)); // add new particles
}
}
explode() {
this.exploded=true;
for (let i=0;i<this.particleCount;i++) { // distribution of particles
this.particles[i].x = this.x + random(-0.2,0.2);
this.particles[i].y = this.y + random(-0.2,0.2);
}
}
}
class Particle {
constructor(parent,color) { // receives parent for signaling the end
this.parent = parent;
this.size = random(7,10); // random size
this.color = color;
this.vx=0;
this.vy=0;
this.x=0;
this.y=0;
this.gFactor=random(2.9,3.5); // decides how fast particle flies
this.alive=true;
}
move() {
this.x += this.vx;
this.y += this.vy;
}
accelerate() {
let d = max(10,dist(this.x,this.y,this.parent.x,this.parent.y));
let ug = -200*this.size/pow(d,this.gFactor); // pushing away particles
let ax = (this.parent.x - this.x)*ug;
let ay = (this.parent.y - this.y)*ug;
this.vx+=ax;
this.vy+=ay+0.016; // gravity toward the ground
this.vx*=0.9; // drag-like force
this.vy*=0.9;
}
burn() { // burnt particles become smaller and later dies
this.size*=0.975;
if (this.size<0.1) {
this.alive = false;
this.parent.particleEnded+=1; // signal parent that particle died
}
}
update() {
if (this.alive) {
this.accelerate(); // change speed
this.move(); // change position
this.draw(); // draw particle (self)
this.burn(); // become smaller
}
}
draw() {
push();
stroke(this.color,this.color,95);
strokeWeight(this.size);
point(this.x,this.y); // draws the particle
pop();
}
}