Skip to content

Instantly share code, notes, and snippets.

@DMax-YT

DMax-YT/snow.js Secret

Last active December 7, 2021 17:43
Show Gist options
  • Save DMax-YT/1512b7ab5c9b98a4969b0b2b1d5f4a95 to your computer and use it in GitHub Desktop.
Save DMax-YT/1512b7ab5c9b98a4969b0b2b1d5f4a95 to your computer and use it in GitHub Desktop.
Snow controller in discord.
const microtime = () => new Date().getTime() * 0.001;
const frand = (min, max) => (min || 0) + Math.random() * ((max || 1) - (min || 0));
class Vector2 {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
add(other) {
this.x += other.x;
this.y += other.y;
}
magnitude() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
}
class Particle {
constructor(origin, velocity, size, amplitude) {
this.origin = origin;
this.position = new Vector2(origin.x, origin.y);
this.velocity = velocity || new Vector2(0, 0);
this.size = size;
this.amplitude = amplitude;
this.dx = Math.random() * 100;
}
update(deltaTime) {
this.position.y += this.velocity.y * deltaTime;
this.dx += this.velocity.x * deltaTime;
this.position.x = this.origin.x + (this.amplitude * Math.sin(this.dx));
}
}
class SnowCanvas {
constructor() {
this.amount = 5000;
this.size = { min: 0.5, max: 1.5 };
this.swing = { min: 0.1, max: 1 };
this.speed = { min: 40, max: 100 };
this.amplitude = { min: 25, max: 50 };
this.particles = [];
this.running = false;
this.startTime = 0;
this.frameTime = 0;
this.init();
}
destroy() {
this.canvas.remove();
}
setAmount(amount) {
this.amount = amount;
return this;
}
setMinSize(size) {
this.size.min = size;
return this;
}
setMaxSize(size) {
this.size.max = size;
return this;
}
setMinSwing(swing) {
this.swing.min = swing;
return this;
}
setMaxSwing(swing) {
this.swing.max = swing;
return this;
}
setMinSpeed(speed) {
this.speed.min = speed;
return this;
}
setMaxSpeed(speed) {
this.speed.max = speed;
return this;
}
setMinAmp(amp) {
this.amplitude.min = amp;
return this;
}
setMaxAmp(amp) {
this.amplitude.max = amp;
return this;
}
init() {
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.id = "snow-canvas";
canvas.style = "display: block;position: absolute;pointer-events: none;z-index: 1000000;"
this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this._resize(window.innerWidth, window.innerHeight);
this._init_particles();
window.addEventListener("resize", () => {
this._resize(window.innerWidth, window.innerHeight);
this._init_particles();
});
return this;
}
start() {
this.running = true;
this.startTime = this.frameTime = microtime();
this._loop();
return this;
}
stop() {
this.running = false;
this._clear();
return this;
}
_resize(w, h) {
this.canvas.width = w;
this.canvas.height = h;
}
_init_particles() {
this.particles = [...Array(this.amount).keys()].map(() => {
const origin = new Vector2(frand(0, this.canvas.width), frand(-this.canvas.height, 0));
const velocity = new Vector2(frand(this.swing.min, this.swing.max), frand(this.speed.min, this.speed.max));
const size = frand(this.size.min, this.size.max);
const amplitude = frand(this.amplitude.min, this.amplitude.max);
return new Particle(origin, velocity, size, amplitude);
});
}
_clear() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
_update() {
const nowTime = microtime();
const deltaTime = nowTime - this.frameTime;
this.particles.forEach((particle) => {
particle.update(deltaTime);
if (particle.position.y - particle.size > this.canvas.height) {
particle.position.y = -particle.size;
particle.position.x = particle.origin.x = Math.random() * this.canvas.width;
particle.dx = Math.random() * 100;
}
});
this.frameTime = nowTime;
}
_draw() {
this.ctx.fillStyle = "rgb(255,255,255)";
this.particles.forEach((particle) =>
this.ctx.fillRect(particle.position.x, particle.position.y, particle.size, particle.size)
);
}
_loop() {
if (this.running) {
this._clear();
this._update();
this._draw();
this._queue();
}
}
_queue() {
window.requestAnimationFrame(this._loop.bind(this));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment