159 lines
4.0 KiB
JavaScript
159 lines
4.0 KiB
JavaScript
const Victor = require("victor");
|
|
const dat = require("dat.gui");
|
|
|
|
// TODO cycle this bkg color
|
|
const BACKGROUND_COLOR = 'rgba(11, 51, 100, 1)';
|
|
const PARTICLE_RADIUS = 1;
|
|
const G_POINT_RADIUS = 10;
|
|
const G_POINT_RADIUS_LIMITS = 65;
|
|
|
|
const canvas = document.getElementById("mainCanvas");
|
|
const bufferCvs = document.createElement("canvas");
|
|
const context = canvas.getContext('2d');
|
|
const bufferCtx = bufferCvs.getContext('2d');
|
|
|
|
let screenWidth = canvas.width = window.innerWidth;
|
|
let screenHeight = canvas.height = window.innerHeight;
|
|
|
|
|
|
let grad = null;
|
|
|
|
const resize = (e) => {
|
|
screenWidth = canvas.width = window.innerWidth;
|
|
screenHeight = canvas.height = window.innerHeight;
|
|
bufferCvs.width = screenWidth;
|
|
bufferCvs.height = screenHeight;
|
|
|
|
// create circular gradient that fills the screen
|
|
const cx = canvas.width / 2;
|
|
const cy = canvas.height / 2;
|
|
|
|
grad =context.createRadialGradient(cx, cy, 0, cx, cy, Math.sqrt(cx * cx + cy * cy));
|
|
grad.addColorStop(0, 'rgba(0, 0, 0, 0)');
|
|
grad.addColorStop(1, 'rgba(0, 0, 0, 0.35)');
|
|
};
|
|
|
|
window.addEventListener('resize', resize, false);
|
|
resize(null);
|
|
|
|
class Particle {
|
|
constructor(x, y, radius) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.radius = radius;
|
|
this._latest = new Victor();
|
|
this._speed = new Victor();
|
|
}
|
|
|
|
addSpeed(speedVec) {
|
|
this._speed.add(speedVec);
|
|
}
|
|
|
|
update() {
|
|
|
|
if (this._speed.length() > 12) {
|
|
this._speed.normalize().scale(12);
|
|
}
|
|
|
|
this._latest.set(this);
|
|
this.add(this._speed);
|
|
}
|
|
}
|
|
|
|
const particles = [];
|
|
const addParticle = (num) => {
|
|
for (var i = 0; i < num; i++) {
|
|
const x = Math.floor(Math.random() * screenWidth - PARTICLE_RADIUS * 2) + 1 + PARTICLE_RADIUS;
|
|
const y = Math.floor(Math.random() * screenHeight - PARTICLE_RADIUS * 2) + 1 + PARTICLE_RADIUS;
|
|
const p = new Particle(x, y, PARTICLE_RADIUS);
|
|
const speed = new Victor(Math.random() * 2 - 1, Math.random() * 2 - 1);
|
|
p.addSpeed(speed);
|
|
particles.push(p);
|
|
}
|
|
};
|
|
|
|
const removeParticle = (num) => {
|
|
if (particles.length < num) {
|
|
num = particles.length;
|
|
}
|
|
for (var i = 0; i < num; i++) {
|
|
particles.pop();
|
|
}
|
|
};
|
|
|
|
const controls = {
|
|
particleNum: 100
|
|
};
|
|
|
|
const gui = new dat.GUI();
|
|
gui.add(controls, "particleNum").min(0).max(500).step(1).name("Particle Num").onChange(function() {
|
|
var n = (controls.particleNum | 0) - particles.length;
|
|
if (n > 0) {
|
|
addParticle(n);
|
|
} else if (n < 0) {
|
|
removeParticle(-n);
|
|
}
|
|
});
|
|
//gui.add(GravityPoint, 'interferenceToPoint').name('Interference Between Point');
|
|
gui.close();
|
|
|
|
const x = new Victor(1,24);
|
|
const y = new Victor(2,485);
|
|
console.log(x.add(y), x, y);
|
|
|
|
|
|
console.log("Finished initting");
|
|
|
|
const loop = (timestamp) => {
|
|
window.requestAnimationFrame(loop);
|
|
|
|
const cx = canvas.width / 2;
|
|
const cy = canvas.height / 2;
|
|
|
|
context.save();
|
|
context.fillStyle = BACKGROUND_COLOR;
|
|
context.fillRect(0, 0, screenWidth, screenHeight);
|
|
|
|
context.fillStyle = grad;
|
|
context.fillRect(0, 0, screenWidth, screenHeight);
|
|
context.restore();
|
|
|
|
|
|
bufferCtx.save();
|
|
bufferCtx.globalCompositeOperation = 'destination-out';
|
|
bufferCtx.globalAlpha = 0.35;
|
|
bufferCtx.fillRect(0, 0, screenWidth, screenHeight);
|
|
bufferCtx.restore();
|
|
|
|
|
|
bufferCtx.save();
|
|
bufferCtx.fillStyle = bufferCtx.strokeStyle = '#fff';
|
|
bufferCtx.lineCap = bufferCtx.lineJoin = 'round';
|
|
bufferCtx.lineWidth = PARTICLE_RADIUS * 2;
|
|
bufferCtx.beginPath();
|
|
|
|
const len = particles.length;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
p = particles[i];
|
|
p.update();
|
|
bufferCtx.moveTo(p.x, p.y);
|
|
bufferCtx.lineTo(p._latest.x, p._latest.y);
|
|
}
|
|
bufferCtx.stroke();
|
|
bufferCtx.beginPath();
|
|
for (i = 0; i < len; i++) {
|
|
p = particles[i];
|
|
bufferCtx.moveTo(p.x, p.y);
|
|
bufferCtx.arc(p.x, p.y, p.radius, 0, Math.PI * 2, false);
|
|
}
|
|
bufferCtx.fill();
|
|
bufferCtx.restore();
|
|
|
|
context.drawImage(bufferCvs, 0, 0);
|
|
|
|
};
|
|
|
|
|
|
loop();
|