diff options
Diffstat (limited to 'scripts/script.js')
-rw-r--r-- | scripts/script.js | 117 |
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); +}; |