260 lines
8.1 KiB
JavaScript
260 lines
8.1 KiB
JavaScript
/**
|
|
* Main JavaScript file for argobox.com
|
|
* Handles animations, interactions, and dynamic content
|
|
*/
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Initialize all website functionality
|
|
initNavigation();
|
|
initParticlesAndIcons();
|
|
initTerminalTyping();
|
|
updateYear();
|
|
});
|
|
|
|
/**
|
|
* Set up navigation functionality - mobile menu and scroll spy
|
|
*/
|
|
function initNavigation() {
|
|
const menuToggle = document.querySelector('.menu-toggle');
|
|
const navMenu = document.querySelector('.nav-menu');
|
|
const navLinks = document.querySelectorAll('.nav-link');
|
|
|
|
if (menuToggle && navMenu) {
|
|
// Toggle mobile menu
|
|
menuToggle.addEventListener('click', () => {
|
|
toggleMobileMenu();
|
|
});
|
|
|
|
// Close mobile menu when clicking outside
|
|
document.addEventListener('click', (e) => {
|
|
if (navMenu.classList.contains('show') &&
|
|
!navMenu.contains(e.target) &&
|
|
!menuToggle.contains(e.target)) {
|
|
toggleMobileMenu();
|
|
}
|
|
});
|
|
|
|
// Close mobile menu when link is clicked
|
|
navLinks.forEach(link => {
|
|
link.addEventListener('click', () => {
|
|
if (window.innerWidth <= 768 && navMenu.classList.contains('show')) {
|
|
toggleMobileMenu();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Handle resize events
|
|
window.addEventListener('resize', () => {
|
|
if (window.innerWidth > 768 && navMenu.classList.contains('show')) {
|
|
navMenu.classList.remove('show');
|
|
updateMenuIcon(false);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Toggle function for mobile menu
|
|
function toggleMobileMenu() {
|
|
navMenu.classList.toggle('show');
|
|
updateMenuIcon(navMenu.classList.contains('show'));
|
|
|
|
// Prevent body scrolling when menu is open
|
|
if (navMenu.classList.contains('show')) {
|
|
document.body.style.overflow = 'hidden';
|
|
} else {
|
|
document.body.style.overflow = '';
|
|
}
|
|
}
|
|
|
|
// Update menu icon based on menu state
|
|
function updateMenuIcon(isOpen) {
|
|
const icon = menuToggle.querySelector('i');
|
|
if (isOpen) {
|
|
icon.classList.remove('fa-bars');
|
|
icon.classList.add('fa-times');
|
|
} else {
|
|
icon.classList.remove('fa-times');
|
|
icon.classList.add('fa-bars');
|
|
}
|
|
}
|
|
|
|
// Scroll spy for navigation
|
|
window.addEventListener('scroll', () => {
|
|
const sections = document.querySelectorAll('section');
|
|
|
|
let current = '';
|
|
sections.forEach(section => {
|
|
const sectionTop = section.offsetTop;
|
|
if (window.scrollY >= sectionTop - 100) {
|
|
current = section.getAttribute('id');
|
|
}
|
|
});
|
|
|
|
navLinks.forEach(link => {
|
|
link.classList.remove('active');
|
|
if (link.getAttribute('href').substring(1) === current) {
|
|
link.classList.add('active');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create background particles and floating tech icons
|
|
*/
|
|
function initParticlesAndIcons() {
|
|
createBackgroundParticles();
|
|
createFloatingIcons();
|
|
}
|
|
|
|
/**
|
|
* Optimize images for better mobile performance
|
|
*/
|
|
function optimizeImagesForMobile() {
|
|
if (window.innerWidth <= 768) {
|
|
// Reduce particles count on mobile for better performance
|
|
createBackgroundParticles(15); // Fewer particles
|
|
} else {
|
|
createBackgroundParticles(50); // Normal number of particles
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create animated background particles
|
|
*/
|
|
function createBackgroundParticles(count = 50) {
|
|
const particlesContainer = document.getElementById('particles-container');
|
|
|
|
if (!particlesContainer) return;
|
|
|
|
// Clear existing particles
|
|
particlesContainer.innerHTML = '';
|
|
|
|
// Create particles
|
|
for (let i = 0; i < count; i++) {
|
|
const particle = document.createElement('div');
|
|
particle.classList.add('particle');
|
|
|
|
// Random size between 2 and 6px
|
|
const size = Math.random() * 4 + 2;
|
|
particle.style.width = `${size}px`;
|
|
particle.style.height = `${size}px`;
|
|
|
|
// Random position
|
|
particle.style.left = `${Math.random() * 100}%`;
|
|
particle.style.top = `${Math.random() * 100}%`;
|
|
|
|
// Random opacity between 0.1 and 0.3
|
|
particle.style.opacity = (Math.random() * 0.2 + 0.1).toString();
|
|
|
|
// Animation properties
|
|
particle.style.animation = `float-particle ${Math.random() * 20 + 10}s linear infinite`;
|
|
particle.style.animationDelay = `${Math.random() * 10}s`;
|
|
|
|
particlesContainer.appendChild(particle);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize terminal typing animation
|
|
*/
|
|
function initTerminalTyping() {
|
|
const cursor = document.querySelector('.cursor');
|
|
if (cursor) {
|
|
setInterval(() => {
|
|
cursor.style.opacity = cursor.style.opacity === '0' ? '1' : '0';
|
|
}, 600);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update copyright year in the footer
|
|
*/
|
|
function updateYear() {
|
|
const yearElement = document.getElementById('current-year');
|
|
if (yearElement) {
|
|
yearElement.textContent = new Date().getFullYear();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create and initialize floating icons in the hero section
|
|
*/
|
|
function createFloatingIcons() {
|
|
// Implemented if needed for mobile
|
|
}
|
|
|
|
// Initialize responsive behaviors
|
|
window.addEventListener('resize', () => {
|
|
optimizeImagesForMobile();
|
|
});
|
|
|
|
// Call once on page load
|
|
optimizeImagesForMobile();
|
|
|
|
// Contact Form Handler
|
|
const contactForm = document.getElementById('contact-form');
|
|
if (contactForm) {
|
|
contactForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
|
|
const submitButton = contactForm.querySelector('button[type="submit"]');
|
|
const originalButtonText = submitButton.innerHTML;
|
|
|
|
try {
|
|
submitButton.disabled = true;
|
|
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...';
|
|
|
|
const formData = new FormData(contactForm);
|
|
const data = {
|
|
name: formData.get('name'),
|
|
email: formData.get('email'),
|
|
subject: formData.get('subject'),
|
|
message: formData.get('message')
|
|
};
|
|
|
|
const response = await fetch('/contact', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(data)
|
|
});
|
|
|
|
const result = await response.json();
|
|
|
|
if (response.ok) {
|
|
// Show success message
|
|
const successMessage = document.createElement('div');
|
|
successMessage.className = 'alert alert-success';
|
|
successMessage.innerHTML = '<i class="fas fa-check-circle"></i> Message sent successfully! We\'ll get back to you soon.';
|
|
contactForm.insertBefore(successMessage, submitButton);
|
|
contactForm.reset();
|
|
|
|
// Remove success message after 5 seconds
|
|
setTimeout(() => {
|
|
successMessage.remove();
|
|
}, 5000);
|
|
} else {
|
|
throw new Error(result.error || 'Failed to send message');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Error sending email:', error);
|
|
|
|
// Show error message
|
|
const errorMessage = document.createElement('div');
|
|
errorMessage.className = 'alert alert-error';
|
|
errorMessage.innerHTML = '<i class="fas fa-exclamation-circle"></i> Failed to send message. Please try again later.';
|
|
contactForm.insertBefore(errorMessage, submitButton);
|
|
|
|
// Remove error message after 5 seconds
|
|
setTimeout(() => {
|
|
errorMessage.remove();
|
|
}, 5000);
|
|
|
|
} finally {
|
|
submitButton.disabled = false;
|
|
submitButton.innerHTML = originalButtonText;
|
|
}
|
|
});
|
|
} |