Files
2026-03-22 00:54:28 -07:00

127 lines
3.8 KiB
JavaScript
Executable File

/**
* UGH.im — Modern theme interactions
*/
const CONFIG = {
particleCount: 80,
musicVolume: 0.4,
themes: [
{ bg: "#0c0c0c", accent: "#f43f5e", hover: "#fb7185" },
{ bg: "#0a0f14", accent: "#38bdf8", hover: "#7dd3fc" },
{ bg: "#0d1117", accent: "#7ee787", hover: "#bbf7d0" },
{ bg: "#0f0a14", accent: "#a78bfa", hover: "#c4b5fd" },
{ bg: "#140a0a", accent: "#f87171", hover: "#fca5a5" }
]
};
/* ==========================================================================
Discordian Date
========================================================================== */
const fetchDiscordianDate = async () => {
try {
const response = await fetch("./ddate-now");
const date = await response.text();
document.getElementById("ddate").textContent = date.trim();
} catch {
document.getElementById("ddate").textContent = "Welcome to UGH.im";
}
};
fetchDiscordianDate();
/* ==========================================================================
Ambient Particles (subtle)
========================================================================== */
const canvas = document.getElementById("stars-bg");
if (canvas) {
const ctx = canvas.getContext("2d");
let width, height;
const particles = [];
const resize = () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
};
class Particle {
constructor() {
this.reset();
}
reset() {
this.x = Math.random() * width;
this.y = Math.random() * height;
this.size = Math.random() * 1.5 + 0.5;
this.speed = Math.random() * 0.3 + 0.05;
this.opacity = Math.random() * 0.4 + 0.1;
}
update() {
this.y += this.speed;
if (this.y > height) this.y = 0;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(244, 63, 94, ${this.opacity})`;
ctx.fill();
}
}
resize();
for (let i = 0; i < CONFIG.particleCount; i++) particles.push(new Particle());
const animate = () => {
ctx.fillStyle = "rgba(12, 12, 12, 0.15)";
ctx.fillRect(0, 0, width, height);
particles.forEach(p => {
p.update();
p.draw();
});
requestAnimationFrame(animate);
};
animate();
window.addEventListener("resize", resize);
}
/* ==========================================================================
Theme Changer
========================================================================== */
let themeIndex = 0;
window.changeTheme = () => {
themeIndex = (themeIndex + 1) % CONFIG.themes.length;
const t = CONFIG.themes[themeIndex];
document.documentElement.style.setProperty("--bg-primary", t.bg);
document.documentElement.style.setProperty("--accent", t.accent);
document.documentElement.style.setProperty("--accent-hover", t.hover);
};
/* ==========================================================================
Music
========================================================================== */
const bgMusic = document.getElementById("bg-music");
let musicPlaying = false;
window.toggleMusic = () => {
const btn = document.querySelector('button[onclick="toggleMusic()"]');
if (musicPlaying) {
bgMusic.pause();
musicPlaying = false;
if (btn) btn.textContent = "🎵 Play Music";
} else {
bgMusic.volume = CONFIG.musicVolume;
bgMusic.play()
.then(() => {
musicPlaying = true;
if (btn) btn.textContent = "🔇 Stop Music";
})
.catch(() => {
if (btn) btn.textContent = "🎵 Play Music";
});
}
};