Files
2026-09-16 23:20:08 +07:00

137 lines
4.2 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
initThemeManager();
initParticleSystem();
initFormInteractions();
});
// --- Theme Manager ---
function initThemeManager() {
const htmlElement = document.documentElement;
const themeBtn = document.getElementById('themeToggleBtn');
const themeIcon = document.getElementById('themeIcon');
// Check local storage or system preference
const savedTheme = localStorage.getItem('auth_theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
let currentTheme = savedTheme || (prefersDark ? 'dark' : 'light');
applyTheme(currentTheme);
if (themeBtn) {
themeBtn.addEventListener('click', () => {
currentTheme = currentTheme === 'light' ? 'dark' : 'light';
applyTheme(currentTheme);
});
}
function applyTheme(theme) {
htmlElement.setAttribute('data-bs-theme', theme);
localStorage.setItem('auth_theme', theme);
if (themeIcon) {
themeIcon.className = theme === 'light' ? 'fa-regular fa-moon' : 'fa-regular fa-sun';
}
}
}
// --- Particle System (Lightweight Canvas) ---
function initParticleSystem() {
const canvas = document.getElementById('particleCanvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
let width, height, particles;
function 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() * 2 + 0.5;
this.speedX = (Math.random() - 0.5) * 0.5;
this.speedY = (Math.random() - 0.5) * 0.5;
this.opacity = Math.random() * 0.5 + 0.1;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x < 0 || this.x > width || this.y < 0 || this.y > height) {
this.reset();
}
}
draw() {
// Read current theme to adjust particle color slightly
const theme = document.documentElement.getAttribute('data-bs-theme');
const color = theme === 'dark' ? `rgba(255, 255, 255, ${this.opacity})` : `rgba(0, 0, 0, ${this.opacity * 0.5})`;
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
}
}
function init() {
resize();
particles = [];
const particleCount = Math.min(window.innerWidth / 15, 100); // Responsive count
for (let i = 0; i < particleCount; i++) {
particles.push(new Particle());
}
}
function animate() {
ctx.clearRect(0, 0, width, height);
particles.forEach(p => {
p.update();
p.draw();
});
requestAnimationFrame(animate);
}
window.addEventListener('resize', () => {
resize();
init();
});
init();
animate();
}
// --- Form Interactions & Loading Overlay ---
function initFormInteractions() {
const loginForm = document.getElementById('loginForm');
const loadingOverlay = document.getElementById('loadingOverlay');
const submitBtn = document.getElementById('submitBtn');
if (loginForm && loadingOverlay) {
loginForm.addEventListener('submit', (e) => {
// Prevent multiple submissions
if (loginForm.classList.contains('is-submitting')) {
e.preventDefault();
return;
}
loginForm.classList.add('is-submitting');
loadingOverlay.classList.add('active');
if (submitBtn) {
submitBtn.disabled = true;
submitBtn.innerHTML = '<i class="fa-solid fa-circle-notch fa-spin"></i> กำลังเข้าสู่ระบบ...';
}
// Allow form to submit normally after showing UI
});
}
}