133 lines
3.7 KiB
JavaScript
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);
|