137 lines
4.2 KiB
JavaScript
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
|
|
});
|
|
}
|
|
}
|