summaryrefslogtreecommitdiff
path: root/scripts/script.js
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-04-26 13:26:15 -0700
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-04-26 16:14:57 -0700
commitaf68e1d499f433cfe9b197aaecb13edca04dddf1 (patch)
treedd58b937986e84c38e5ed03dcf6379eea966cf6b /scripts/script.js
downloadrainrainra.in-af68e1d499f433cfe9b197aaecb13edca04dddf1.tar.gz
rainrainra.in-af68e1d499f433cfe9b197aaecb13edca04dddf1.zip
rainrainrainHEADmain
Diffstat (limited to 'scripts/script.js')
-rw-r--r--scripts/script.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/scripts/script.js b/scripts/script.js
new file mode 100644
index 0000000..b3efd73
--- /dev/null
+++ b/scripts/script.js
@@ -0,0 +1,117 @@
+const IMGS = [
+ "/img/rains/arch.png",
+ "/img/rains/bmo.png",
+ "/img/rains/cat.gif",
+ "/img/rains/demi.png",
+ "/img/rains/dnd.png",
+ "/img/rains/eattherich.png",
+ "/img/rains/gloomhaven.png",
+ "/img/rains/iron_throne.png",
+ "/img/rains/link.png",
+ "/img/rains/meddle.jpeg",
+ "/img/rains/moon.png",
+ "/img/rains/note.png",
+ "/img/rains/obsidian.png",
+ "/img/rains/outerwilds.png",
+ "/img/rains/piano.png",
+ "/img/rains/pirate.svg",
+ "/img/rains/ror.png",
+ "/img/rains/smashball.svg",
+ "/img/rains/ssa.png",
+ "/img/rains/svelte.png",
+ "/img/rains/usu.png",
+];
+
+const DROPLETS = 8;
+const DROPLET_WIDTH_RANGE = [80, 120];
+const DROPLET_DY_RANGE = [0.1, 0.4];
+const DROPLET_DTHETA_RANGE = [-0.25, 0.25];
+const DROPLET_INIT_THETA_RANGE = [-180, 180];
+
+const makeDroplet = (src, width, x, y, theta, dtheta, dy) => {
+ const img = document.createElement("img");
+ img.style.position = "absolute";
+ img.style.width = `${width}px`;
+ img.src = src;
+ document.body.appendChild(img);
+
+ return {
+ img,
+ width,
+ theta,
+ pos: { x, y },
+ vel: { dy, dtheta },
+ };
+};
+
+const randBetween = (min, max) => Math.random() * (max - min) + min;
+
+const update = (droplets, dt, boundedY) =>
+ droplets
+ .map((droplet) => {
+ return {
+ ...droplet,
+ pos: { ...droplet.pos, y: droplet.pos.y + droplet.vel.dy * dt },
+ theta: droplet.theta + droplet.vel.dtheta * dt,
+ };
+ })
+ .map((droplet) => {
+ const {
+ pos: { y },
+ img,
+ } = droplet;
+ if (y >= boundedY) {
+ document.body.removeChild(img);
+ return null;
+ }
+ return droplet;
+ })
+ .filter((x) => x)
+ .map((droplet) => {
+ const {
+ img,
+ pos: { x, y },
+ theta,
+ } = droplet;
+
+ img.style.left = `${x}px`;
+ img.style.top = `${y}px`;
+ img.style.transform = `rotate(${theta}deg)`;
+
+ return droplet;
+ });
+
+const buildRandomDroplet = () =>
+ makeDroplet(
+ IMGS[Math.floor(randBetween(0, IMGS.length))],
+ randBetween(...DROPLET_WIDTH_RANGE),
+ randBetween(0, window.innerWidth - DROPLET_WIDTH_RANGE[1]),
+ randBetween(-50, window.innerHeight / 8),
+ randBetween(...DROPLET_INIT_THETA_RANGE),
+ randBetween(...DROPLET_DTHETA_RANGE),
+ randBetween(...DROPLET_DY_RANGE),
+ );
+
+window.onload = () => {
+ // cache 'em
+ IMGS.forEach((x) => {
+ ((img) => (img.src = x))(new Image());
+ });
+
+ let droplets = Array(DROPLETS).fill().map(buildRandomDroplet);
+
+ let lastTimestamp = performance.now();
+ const next = (timestamp) => {
+ const dt = timestamp - lastTimestamp;
+ lastTimestamp = timestamp;
+
+ droplets = update(droplets, dt, window.innerHeight);
+
+ if (droplets.length != DROPLETS) {
+ droplets.push(buildRandomDroplet());
+ }
+
+ requestAnimationFrame(next);
+ };
+ requestAnimationFrame(next);
+};