75 lines
2.2 KiB
JavaScript
75 lines
2.2 KiB
JavaScript
function RainCanvas(canvasDOM) {
|
|
this.canvas = canvasDOM;
|
|
this.ctx = this.canvas.getContext("2d");
|
|
|
|
this.drops = [];
|
|
this.tick = 0;
|
|
|
|
// drop: {x, y, intensity, color} (all in range [0, 1], except color which is
|
|
// an array [r,g,b])
|
|
this.newDrop = (newDrop) => {
|
|
if (!document.hasFocus()) return;
|
|
|
|
// scale intensity up a bit right off the bat. If the intensity was near 0
|
|
// the drop wouldn't actually show up at all.
|
|
newDrop.intensity = distribute(newDrop.intensity, 0, 1, 0.1, 1);
|
|
newDrop.tick = this.tick;
|
|
this.drops.push(newDrop);
|
|
};
|
|
|
|
// alpha isn't really alpha, it's used to determine line width, but it plays
|
|
// the same role.
|
|
this.drawDrop = (drop, alpha) => {
|
|
let cW = this.canvas.width, cH = this.canvas.height;
|
|
let minDim = Math.min(cW, cH);
|
|
|
|
let tickDiff = this.tick - drop.tick;
|
|
let radius = tickDiff * (minDim / 250);
|
|
let x = distribute(drop.x, 0, 1, cW*0.1, cW*0.9);
|
|
let y = distribute(drop.y, 0, 1, cH*0.1, cH*0.9);
|
|
|
|
this.ctx.beginPath();
|
|
this.ctx.arc(x, y, radius, 0, Math.PI * 2, false);
|
|
this.ctx.closePath();
|
|
|
|
// multiple lineWidth by alpha so that the line width drops over time in
|
|
// correspondence with the opacity.
|
|
this.ctx.lineWidth = distribute(drop.intensity, 0, 1, 2, 9) * alpha;
|
|
|
|
let r = drop.color[0], g = drop.color[1], b = drop.color[2];
|
|
this.ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, 1)`;
|
|
this.ctx.stroke();
|
|
};
|
|
|
|
let requestAnimationFrame =
|
|
window.requestAnimationFrame ||
|
|
window.mozRequestAnimationFrame ||
|
|
window.webkitRequestAnimationFrame ||
|
|
window.msRequestAnimationFrame;
|
|
|
|
this.doTick = () => {
|
|
this.canvas.width = window.innerWidth;
|
|
this.canvas.height = window.innerHeight;
|
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
let newDrops = [];
|
|
for (let i in this.drops) {
|
|
let drop = this.drops[i];
|
|
let alpha = distribute(
|
|
this.tick - drop.tick,
|
|
0, 200 * drop.intensity,
|
|
1, 0,
|
|
);
|
|
if (alpha <= 0) continue;
|
|
|
|
this.drawDrop(drop, alpha);
|
|
newDrops.push(drop);
|
|
}
|
|
this.drops = newDrops;
|
|
|
|
this.tick++;
|
|
requestAnimationFrame(this.doTick);
|
|
};
|
|
requestAnimationFrame(this.doTick);
|
|
}
|