File manager - Edit - /home/webapp69.cm.in.th/u69319090023/porfolio/0023/index.js
Back
// DOM Elements const header = document.getElementById('header'); const navMenu = document.getElementById('nav-menu'); const navToggle = document.getElementById('nav-toggle'); const navLinks = document.querySelectorAll('.nav-link'); const currentYearEl = document.getElementById('current-year'); const profileImg = document.querySelector('.profile-img'); const profileFallbackIcon = document.querySelector('.profile-fallback-icon'); const themeToggle = document.getElementById('theme-toggle'); const themeIcon = themeToggle ? themeToggle.querySelector('i') : null; // Update Year if (currentYearEl) { currentYearEl.textContent = new Date().getFullYear(); } // Theme Switcher Logic const updateThemeIcon = (theme) => { if (themeIcon) { if (theme === 'light') { themeIcon.className = 'fa-solid fa-sun'; themeIcon.style.color = 'var(--neon-pink)'; } else { themeIcon.className = 'fa-solid fa-moon'; themeIcon.style.color = 'var(--neon-cyan)'; } } }; // Initialize Theme Toggle State const initialTheme = document.documentElement.getAttribute('data-theme') || 'dark'; updateThemeIcon(initialTheme); if (themeToggle) { themeToggle.addEventListener('click', () => { const currentTheme = document.documentElement.getAttribute('data-theme') || 'dark'; let nextTheme = 'dark'; if (currentTheme === 'dark') { nextTheme = 'light'; document.documentElement.setAttribute('data-theme', 'light'); } else { document.documentElement.removeAttribute('data-theme'); } localStorage.setItem('portfolio-theme', nextTheme); updateThemeIcon(nextTheme); }); } // Header Scroll Interaction window.addEventListener('scroll', () => { if (window.scrollY > 20) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } }); // Scroll Spy for Nav Links Highlight const sections = document.querySelectorAll('section'); const handleScrollSpy = () => { let activeSectionId = ''; sections.forEach(section => { const sectionTop = section.offsetTop; if (window.scrollY >= (sectionTop - 160)) { activeSectionId = section.getAttribute('id'); } }); navLinks.forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === `#${activeSectionId}`) { link.classList.add('active'); } }); }; window.addEventListener('scroll', handleScrollSpy); handleScrollSpy(); // Mobile Hamburger Toggle if (navToggle) { navToggle.addEventListener('click', () => { navMenu.classList.toggle('active'); const icon = navToggle.querySelector('i'); if (navMenu.classList.contains('active')) { icon.className = 'fa-solid fa-xmark'; icon.style.color = 'var(--neon-pink)'; } else { icon.className = 'fa-solid fa-bars'; icon.style.color = 'var(--text-light)'; } }); } // Close Mobile Menu on Click Links navLinks.forEach(link => { link.addEventListener('click', () => { navMenu.classList.remove('active'); if (navToggle) { const icon = navToggle.querySelector('i'); icon.className = 'fa-solid fa-bars'; icon.style.color = 'var(--text-light)'; } }); }); // Fallback Profile Avatar when profile.png is absent if (profileImg) { const testImg = new Image(); testImg.src = profileImg.src; const handleImageError = () => { const container = document.querySelector('.profile-container'); if (container) { container.classList.add('no-image'); container.classList.remove('has-image'); } profileImg.style.display = 'none'; if (profileFallbackIcon) { profileFallbackIcon.style.display = 'block'; } const label = document.querySelector('.profile-scan-label'); if (label) { label.innerHTML = '<i class="fa-solid fa-circle-exclamation"></i> OFFLINE'; label.style.borderColor = 'var(--neon-pink)'; label.style.color = 'var(--neon-pink)'; label.style.textShadow = '0 0 5px var(--neon-pink)'; } }; const handleImageSuccess = () => { const container = document.querySelector('.profile-container'); if (container) { container.classList.add('has-image'); container.classList.remove('no-image'); } }; testImg.onload = handleImageSuccess; profileImg.onload = handleImageSuccess; testImg.onerror = handleImageError; profileImg.onerror = handleImageError; // If already loaded from cache if (profileImg.complete) { if (profileImg.naturalWidth > 0) { handleImageSuccess(); } else { handleImageError(); } } } // Skills bar visual loader const skillBars = document.querySelectorAll('.skill-bar-inner'); const skillPercentages = document.querySelectorAll('.skill-percentage'); const animateSkills = () => { skillBars.forEach(bar => { const targetWidth = bar.getAttribute('data-width'); bar.style.width = targetWidth; }); skillPercentages.forEach(percent => { const targetVal = parseInt(percent.getAttribute('data-val')); let currentVal = 0; const interval = setInterval(() => { if (currentVal >= targetVal) { percent.textContent = targetVal + '%'; clearInterval(interval); } else { currentVal++; percent.textContent = currentVal + '%'; } }, 15); }); }; // Scroll Observer for Skill bars triggers const skillsSection = document.getElementById('skills'); if (skillsSection && 'IntersectionObserver' in window) { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { animateSkills(); observer.unobserve(entry.target); } }); }, { threshold: 0.15 }); observer.observe(skillsSection); } else { // Browser compatibility fallback setTimeout(animateSkills, 800); } // Contact Form Custom Notification Alert (Cyberpunk popup style) const contactForm = document.getElementById('contactForm'); if (contactForm) { contactForm.addEventListener('submit', (e) => { e.preventDefault(); const senderName = document.getElementById('senderName').value; const senderEmail = document.getElementById('senderEmail').value; const senderMessage = document.getElementById('senderMessage').value; // Create custom alert element const toast = document.createElement('div'); toast.style.position = 'fixed'; toast.style.bottom = '30px'; toast.style.right = '30px'; toast.style.background = 'var(--bg-dark)'; toast.style.border = '2px solid var(--neon-cyan)'; toast.style.boxShadow = '0 0 25px rgba(0, 240, 255, 0.4)'; toast.style.borderRadius = '16px'; toast.style.padding = '22px'; toast.style.zIndex = '10000'; toast.style.fontFamily = 'var(--font-head)'; toast.style.color = '#ffffff'; toast.style.maxWidth = '360px'; toast.style.animation = 'fade-in-up 0.5s cubic-bezier(0.25, 0.8, 0.25, 1) forwards'; toast.innerHTML = ` <div style="display:flex; align-items:center; gap: 15px; margin-bottom: 10px;"> <i class="fa-solid fa-satellite-dish" style="color: var(--neon-cyan); font-size: 1.6rem; filter: drop-shadow(0 0 6px var(--neon-cyan));"></i> <span style="font-weight: bold; letter-spacing: 1.5px; color: var(--neon-cyan); font-size: 1.1rem;">DATA TRANSMITTED</span> </div> <p style="font-size: 0.95rem; color: var(--text-gray); line-height: 1.5;"> ส่งข้อความสำเร็จแล้ว! ขอบคุณครับคุณ <strong>${senderName}</strong> ผมจะรีบติดต่อกลับโดยด่วนที่สุด </p> <div style="height: 3px; background: var(--neon-cyan); width: 100%; margin-top: 15px; border-radius: 2px; animation: shrink-bar 3.5s linear forwards;"></div> `; document.body.appendChild(toast); // Add keyframe style dynamically for toast bar animation const animationStyle = document.createElement('style'); animationStyle.textContent = ` @keyframes shrink-bar { from { width: 100%; } to { width: 0%; } } `; document.head.appendChild(animationStyle); // Clear form inputs contactForm.reset(); // Clear notification popup after timer setTimeout(() => { toast.style.animation = 'fade-in-up 0.5s cubic-bezier(0.25, 0.8, 0.25, 1) reverse forwards'; setTimeout(() => { toast.remove(); }, 500); }, 3500); }); }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.31 |
proxy
|
phpinfo
|
Settings