68 lines
2 KiB
JavaScript
68 lines
2 KiB
JavaScript
const m = 76667 * 78887;
|
|
const nextRandom = x => x ** 2 % m
|
|
|
|
const generateRandomArray = (initialSeed, count) => (
|
|
count <= 0
|
|
? []
|
|
: [initialSeed].concat(generateRandomArray(nextRandom(initialSeed), count - 1)))
|
|
|
|
const zip = (f, ...lists) => (
|
|
lists.some(l => l.length == 0)
|
|
? []
|
|
: [f(...lists.map(l => l[0]))].concat(zip(f, ...lists.map(l => l.slice(1)))))
|
|
|
|
const goopZoneElem = document.getElementById("goop-zone");
|
|
const goopHeader = document.getElementById("header-box");
|
|
|
|
const nextState = (state, width, height) => document.hidden ? state : state.map(orig => {
|
|
const projectedNewX = orig.x + orig.vx;
|
|
const projectedNewY = orig.y + orig.vy;
|
|
const [newX, newVX] =
|
|
projectedNewX < 0 || projectedNewX > width
|
|
? [orig.x - orig.vx, -orig.vx]
|
|
: [projectedNewX, orig.vx];
|
|
const [newY, newVY] =
|
|
projectedNewY < -50 || projectedNewY > height - 20
|
|
? [orig.y - orig.vy, -orig.vy]
|
|
: [projectedNewY, orig.vy];
|
|
return ({
|
|
elem: orig.elem,
|
|
x: newX,
|
|
y: newY,
|
|
vx: newVX,
|
|
vy: newVY
|
|
})
|
|
});
|
|
|
|
const mkInitialState = (drifters, width, height) => zip(
|
|
(elem, random1, random2, random3) => (direction =>
|
|
({ elem: elem
|
|
, x: random1 % width
|
|
, y: random2 % height
|
|
, vx: 20 * Math.cos(direction)
|
|
, vy: 20 * Math.sin(direction)
|
|
})
|
|
)(random3 % 2000 / 1000 * Math.PI),
|
|
drifters,
|
|
generateRandomArray(5737051, drifters.length),
|
|
generateRandomArray(5457297, drifters.length),
|
|
generateRandomArray(3631413, drifters.length))
|
|
|
|
const applyState = states => states.map(s => {
|
|
s.elem.setAttribute('style', `transform: translate(${s.x}px, ${s.y}px)`)
|
|
});
|
|
|
|
loop = (state) => {
|
|
setInterval(() => {
|
|
const goopZoneWidth = goopZoneElem.width.baseVal.value;
|
|
const goopZoneHeight = goopZoneElem.height.baseVal.value;
|
|
|
|
goopHeader.setAttribute("x", goopZoneWidth/2-300);
|
|
|
|
state = nextState(state, goopZoneWidth, goopZoneHeight);
|
|
applyState(state)
|
|
}, 500)
|
|
}
|
|
|
|
const drifters = Array.from(document.getElementsByClassName("glob"));
|
|
loop(mkInitialState(drifters, goopZoneElem.width.baseVal.value, goopZoneElem.height.baseVal.value)); |