public/assets/index2.js
2024-05-22 04:03:59 -07:00

133 lines
3.7 KiB
JavaScript

const pre = document.getElementById("main");
// the cool spinning circles on index.html
const rnd = (n) => Math.floor(Math.random() * n);
const points = [];
let time = 0;
let charRows, charCols, charHeight;
// handle page resizes without ruining everything
function resize() {
const canvas = new OffscreenCanvas(100, 100);
const context = canvas.getContext("2d");
context.font = getComputedStyle(pre).font;
const measured = context.measureText("x");
charHeight = measured.fontBoundingBoxAscent + 5;
charRows = Math.floor((window.innerHeight) / charHeight);
charCols = Math.floor((window.innerWidth - 5) / measured.width);
}
const shades = " .:=+*#%".split("");
// const shades = "01234567".split("");
const shaders = [
// stripes
(t, x, y) => {
return shades[Math.floor(Math.abs((x * t / 30) + (y * t / 15)) * t / 10) % 8]
},
// circles
(t, x, y) => {
return shades[Math.floor(Math.sqrt(x ** 2 + y ** 2) * (t / 10)) % 8]
},
// mandelbrot
(t, x, y) => {
const scale = 20000 / (t + 100) ** 2;
let x0 = x * scale - .803, y0 = y * scale - .167, x1 = 0, y1 = 0, i = 0;
for (; i < 100 && x1 ** 2 + y1 ** 2 <= 2 ** 2; i++) {
const tmp = x1 ** 2 - y1 ** 2 + x0;
y1 = 2 * x1 * y1 + y0;
x1 = tmp;
}
return shades[Math.floor(i) % 8];
},
(t, x, y) => {
const xs = x * t / 3;
const ys = y * t / 3;
return shades[Math.floor(Math.abs((xs % ys || 0) - (ys % xs || 0))) % 8]
},
(t, x, y) => {
const s = ((x / y + t / 10) & 1 / y & 1) && y > 0;
return shades[Math.floor(s) % 8]
},
(t, x, y) => {
return shades[(Math.cos(50*Math.sin((y)/(x))+5*(t/30))+1)*4<<0];
},
// FIXME: broken on some screen resolutions
// (t, x, y) => {
// const rows = [
// " __ ",
// " ________ / /__ _______ __ ___ __ __ ____ _________ _",
// " / ___/ _ \\/ / _ \\/ ___/ / / // _ \\/ / / // __ \\/ ___/ __ `/",
// "/ /__/ __/ / __/ / / /_/ // __/ /_/ // /_/ / / / /_/ / ",
// "\\___/\\___/_/\\___/_/ \\__, (_)___/\\__,_(_)____/_/ \\__, / ",
// " /____/ /____/ ",
// ];
// const tween = Math.sin(t / 30 + x * 2) * 3;
// const ch = rows[Math.round(tween + y * (charRows / 2)) + (rows.length / 2)]?.[Math.round(x * (charCols / 2)) + rows[0].length / 2];
// return ch || " ";
// },
];
// const shader = shaders[Math.random() * shaders.length << 0];
const shader = shaders[2];
function shade(x, y) {
return shader(
time,
(x / (charCols / 2)) - 1,
(y / (charRows / 2)) - 1,
);
}
const rows = [];
function draw() {
if (rows.length !== charRows) {
while (rows.length) rows.pop().remove();
for (let i = 0; i < charRows; i++) {
const el = document.createElementNS("http://www.w3.org/2000/svg", "text");
el.setAttribute("x", 5);
el.setAttribute("y", i * charHeight + charHeight);
el.setAttribute("fill", "grey");
el.style.fontSize = "16px";
el.style.whiteSpace = "pre";
el.textContent = "you are at celery.eu.org";
rows.push(el);
pre.append(el);
}
}
for (let y = 0; y < charRows; y++) {
let buf = "";
for (let x = 0; x < charCols; x++) {
buf += shade(x, y);
}
rows[y].textContent = buf;
}
requestAnimationFrame(draw);
}
function init() {
resize();
window.addEventListener("resize", resize);
for (let i = 0; i < 10; i++) {
points.push({
shade: "celry"[Math.floor(Math.random() * 5)],
radius: Math.random() * 600 + 300,
speed: Math.random() / 10 + 0.1,
rot: Math.random() * 2 * Math.PI,
});
}
draw();
}
init();
setInterval(() => time++, 1000 / 60);