155 lines
3.5 KiB
HTML
155 lines
3.5 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="">
|
||
|
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<title>Space</title>
|
||
|
|
||
|
<style>
|
||
|
body {
|
||
|
background-color: black;
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
width: 100vw;
|
||
|
height: 100vh;
|
||
|
margin: 0;
|
||
|
padding: 0;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
|
||
|
canvas {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
width: 100vw;
|
||
|
height: 100vh;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<canvas id="space"></canvas>
|
||
|
<script>
|
||
|
let images = [
|
||
|
"aubanana.png",
|
||
|
"aublack.png",
|
||
|
"aublue.png",
|
||
|
"aubrown.png",
|
||
|
"aucoral.png",
|
||
|
"aucyan.png",
|
||
|
"augray.png",
|
||
|
"augreen.png",
|
||
|
"aulime.png",
|
||
|
"aumaroon.png",
|
||
|
"auorange.png",
|
||
|
"aupink.png",
|
||
|
"aupurple.png",
|
||
|
"aured.png",
|
||
|
"aurose.png",
|
||
|
"autan.png",
|
||
|
"auwhite.png",
|
||
|
"auyellow.png",
|
||
|
];
|
||
|
|
||
|
let imagesElements = [];
|
||
|
for (let img of images) {
|
||
|
let i = new Image();
|
||
|
i.src = "https://nsfw.cringe-studios.com/amogus/" + img;
|
||
|
imagesElements.push(i);
|
||
|
}
|
||
|
|
||
|
let space = document.getElementById("space");
|
||
|
let ctx = space.getContext("2d");
|
||
|
|
||
|
// Standard Normal variate using Box-Muller transform.
|
||
|
function gaussianRandom(mean = 0, stdev = 1) {
|
||
|
const u = 1 - Math.random(); // Converting [0,1) to (0,1]
|
||
|
const v = Math.random();
|
||
|
const z = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
|
||
|
// Transform to the desired mean and standard deviation:
|
||
|
return z * stdev + mean;
|
||
|
}
|
||
|
|
||
|
function multiplier() {
|
||
|
return Math.random() >= 0.5 ? 1 : -1;
|
||
|
}
|
||
|
|
||
|
let crewmates = [];
|
||
|
for (let i = 0; i < images.length; i++) {
|
||
|
let x = Math.random() * space.clientWidth;
|
||
|
let y = Math.random() * space.clientHeight;
|
||
|
let angle = Math.random() * 360;
|
||
|
let xVel = (Math.random() * 2 + 1) * multiplier();
|
||
|
let yVel = (Math.random() * 2 + 1) * multiplier();
|
||
|
let angleVel = (Math.random() * 1 + 0.1) * multiplier();
|
||
|
let img = i % images.length;
|
||
|
let size = Math.abs(gaussianRandom()) * 0.5 + 0.25;
|
||
|
xVel *= size;
|
||
|
yVel *= size;
|
||
|
|
||
|
crewmates.push({ x, y, angle, xVel, yVel, angleVel, img, size });
|
||
|
}
|
||
|
|
||
|
crewmates.sort((a, b) => a.size - b.size);
|
||
|
|
||
|
let stars = [];
|
||
|
for (let i = 0; i < 100; i++) {
|
||
|
let x = Math.random();
|
||
|
let y = Math.random();
|
||
|
let size = Math.random() * 5 + 3;
|
||
|
stars.push({ x, y, size });
|
||
|
}
|
||
|
|
||
|
setInterval(() => {
|
||
|
space.width = space.clientWidth;
|
||
|
space.height = space.clientHeight;
|
||
|
|
||
|
ctx.fillStyle = "white";
|
||
|
for (let star of stars) {
|
||
|
ctx.fillRect(star.x * space.clientWidth - star.size / 2, star.y * space.clientHeight - star.size / 2, star.size, star.size);
|
||
|
}
|
||
|
|
||
|
let targetImageSize = 256;
|
||
|
let actualImageSize = Math.max(imagesElements[0].width, imagesElements[0].height) * Math.sqrt(2);
|
||
|
let imageScale = targetImageSize / actualImageSize;
|
||
|
for (let crewmate of crewmates) {
|
||
|
crewmate.x += crewmate.xVel;
|
||
|
crewmate.y += crewmate.yVel;
|
||
|
crewmate.angle += crewmate.angleVel;
|
||
|
|
||
|
let delta = crewmate.size * targetImageSize;
|
||
|
|
||
|
if (crewmate.x < -delta) {
|
||
|
crewmate.x += space.width + 2 * delta;
|
||
|
}
|
||
|
|
||
|
if (crewmate.y < -delta) {
|
||
|
crewmate.y += space.height + 2 * delta;
|
||
|
}
|
||
|
|
||
|
if (crewmate.x > space.width + delta) {
|
||
|
crewmate.x -= space.width + 2 * delta;
|
||
|
}
|
||
|
|
||
|
if (crewmate.y > space.height + delta) {
|
||
|
crewmate.y -= space.height + 2 * delta;
|
||
|
}
|
||
|
|
||
|
let img = imagesElements[crewmate.img];
|
||
|
|
||
|
ctx.save();
|
||
|
ctx.translate(crewmate.x, crewmate.y);
|
||
|
ctx.scale(imageScale, imageScale);
|
||
|
ctx.scale(crewmate.size, crewmate.size);
|
||
|
ctx.rotate(crewmate.angle / 360 * Math.PI * 2);
|
||
|
ctx.drawImage(img, -img.width / 2, -img.height / 2);
|
||
|
ctx.restore();
|
||
|
}
|
||
|
|
||
|
}, 20);
|
||
|
</script>
|
||
|
</body>
|
||
|
|
||
|
</html>
|