Spaces:
Running
Running
| // Main JavaScript for MileTruck Project | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize components | |
| initializeStatsCounter(); | |
| initializeFleetGallery(); | |
| initializePartnerLogos(); | |
| initializeFleetNavigation(); | |
| // Add smooth scroll to anchor links | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const targetId = this.getAttribute('href'); | |
| if (targetId === '#') return; | |
| const targetElement = document.querySelector(targetId); | |
| if (targetElement) { | |
| window.scrollTo({ | |
| top: targetElement.offsetTop - 80, | |
| behavior: 'smooth' | |
| }); | |
| } | |
| }); | |
| }); | |
| }); | |
| // Stats Counter Animation | |
| function initializeStatsCounter() { | |
| const statElements = document.querySelectorAll('.stat-counter'); | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const element = entry.target; | |
| const target = parseFloat(element.getAttribute('data-target')); | |
| const suffix = element.textContent.includes('مليون') ? ' مليون' : | |
| element.textContent.includes('مليار') ? ' مليار' : | |
| element.textContent.includes(' ألف') ? ' ألف' : ''; | |
| let start = 0; | |
| const duration = 2000; // 2 seconds | |
| const increment = target / (duration / 16); // 60fps | |
| const timer = setInterval(() => { | |
| start += increment; | |
| if (start >= target) { | |
| element.textContent = formatNumber(target) + suffix; | |
| clearInterval(timer); | |
| } else { | |
| element.textContent = formatNumber(Math.floor(start)) + suffix; | |
| } | |
| }, 16); | |
| observer.unobserve(element); | |
| } | |
| }); | |
| }, { threshold: 0.5 }); | |
| statElements.forEach(el => observer.observe(el)); | |
| } | |
| function formatNumber(num) { | |
| if (num >= 1000000) { | |
| return (num / 1000000).toFixed(1).replace('.0', ''); | |
| } | |
| return num.toLocaleString('en-US'); | |
| } | |
| // Fleet Gallery Initialization | |
| function initializeFleetGallery() { | |
| const fleetData = [ | |
| { | |
| category: 'traila', | |
| type: 'تريلا', | |
| name: 'تريلا سطحة محورين', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/traila/flatbed-trailer-2axles.webp', | |
| length: 'طول المقطورة حتى 13.5 متر', | |
| capacity: 'حمولة قصوى 25 طن' | |
| }, | |
| { | |
| category: 'traila', | |
| type: 'تريلا', | |
| name: 'تريلا سطحة ثلاث محاور', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/traila/flatbed-trailer-3axles.webp', | |
| length: 'طول المقطورة حتى 13.5 متر', | |
| capacity: 'حمولة قصوى 30 طن' | |
| }, | |
| { | |
| category: 'traila', | |
| type: 'تريلا', | |
| name: 'تريلا ستارة', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/traila/curtain-trailer.webp', | |
| length: 'طول المقطورة حتى 13.5 متر', | |
| capacity: 'حمولة قصوى 25 طن' | |
| }, | |
| { | |
| category: 'traila', | |
| type: 'تريلا', | |
| name: 'تريلا جوانب عالية', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/traila/high-sided-trailer.webp', | |
| length: 'طول المقطورة حتى 15 متر', | |
| capacity: 'حمولة قصوى 20 طن' | |
| }, | |
| { | |
| category: 'six', | |
| type: 'سقس', | |
| name: 'سقس جوانب عالية', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/six/sax-high-sided.webp', | |
| length: 'الطول حتى 8 متر', | |
| capacity: 'حمولة قصوى 13 طن' | |
| }, | |
| { | |
| category: 'six', | |
| type: 'سقس', | |
| name: 'سقس ثلاجة', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/six/sax-refrigerated.webp', | |
| length: 'الطول حتى 8 متر', | |
| capacity: 'حمولة قصوى 10 طن' | |
| }, | |
| { | |
| category: 'lorry', | |
| type: 'لوري', | |
| name: 'لوري شبك', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/lorry/Lorry-Cage-Truck-7M.webp', | |
| length: 'الطول حتى 7.5 متر', | |
| capacity: 'حمولة قصوى 8 طن' | |
| }, | |
| { | |
| category: 'lorry', | |
| type: 'لوري', | |
| name: 'لوري جاف (مغلق)', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/lorry/closed-lorry.webp', | |
| length: 'الطول حتى 6.5 متر', | |
| capacity: 'حمولة قصوى 6 طن' | |
| }, | |
| { | |
| category: 'dyna', | |
| type: 'دينا', | |
| name: 'دينا شبك', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/dyna/open-dyna.webp', | |
| length: 'الطول حتى 6 متر', | |
| capacity: 'حمولة قصوى 4 طن' | |
| }, | |
| { | |
| category: 'pickup', | |
| type: 'بكب', | |
| name: 'بكب', | |
| image: 'https://www.shahen-sa.com/assets/images/home/truck-images/pickup/Pickup-Truck.webp', | |
| length: 'الطول حتى 5 متر', | |
| capacity: 'حمولة قصوى 2 طن' | |
| } | |
| ]; | |
| const container = document.querySelector('.fleet-container'); | |
| function renderFleetItems(filter = 'all') { | |
| container.innerHTML = ''; | |
| const filteredFleet = filter === 'all' | |
| ? fleetData | |
| : fleetData.filter(item => item.category === filter); | |
| filteredFleet.forEach((item, index) => { | |
| const fleetCard = document.createElement('div'); | |
| fleetCard.className = `fleet-card bg-white rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-shadow duration-300`; | |
| fleetCard.style.animationDelay = `${index * 100}ms`; | |
| fleetCard.innerHTML = ` | |
| <div class="relative h-48 overflow-hidden"> | |
| <img src="${item.image}" alt="${item.name}" class="w-full h-full object-cover hover:scale-110 transition-transform duration-500"> | |
| <div class="absolute top-3 right-3 bg-primary text-white px-3 py-1 rounded-full text-sm"> | |
| ${item.type} | |
| </div> | |
| </div> | |
| <div class="p-6"> | |
| <h3 class="text-xl font-semibold mb-2 text-dark">${item.name}</h3> | |
| <div class="space-y-2 text-gray-600"> | |
| <div class="flex items-center"> | |
| <i data-feather="maximize" class="w-4 h-4 ml-2"></i> | |
| <span>${item.length}</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i data-feather="package" class="w-4 h-4 ml-2"></i> | |
| <span>${item.capacity}</span> | |
| </div> | |
| </div> | |
| <button class="mt-4 w-full bg-gray-100 hover:bg-primary hover:text-white text-primary font-medium py-2 rounded-lg transition-colors duration-300 flex items-center justify-center"> | |
| <i data-feather="shopping-cart" class="ml-2"></i> | |
| طلب هذه المركبة | |
| </button> | |
| </div> | |
| `; | |
| container.appendChild(fleetCard); | |
| }); | |
| // Re-initialize feather icons for new elements | |
| feather.replace(); | |
| } | |
| window.renderFleetItems = renderFleetItems; | |
| renderFleetItems(); // Initial render | |
| } | |
| // Fleet Navigation | |
| function initializeFleetNavigation() { | |
| const categoryButtons = document.querySelectorAll('.fleet-category-btn'); | |
| categoryButtons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| // Remove active class from all buttons | |
| categoryButtons.forEach(btn => { | |
| btn.classList.remove('active', 'bg-primary', 'text-white'); | |
| btn.classList.add('bg-gray-100', 'hover:bg-gray-200'); | |
| }); | |
| // Add active class to clicked button | |
| this.classList.add('active', 'bg-primary', 'text-white'); | |
| this.classList.remove('bg-gray-100', 'hover:bg-gray-200'); | |
| // Filter fleet items | |
| const category = this.getAttribute('data-category'); | |
| renderFleetItems(category); | |
| }); | |
| }); | |
| } | |
| // Partner Logos | |
| function initializePartnerLogos() { | |
| const partnerLogos = [ | |
| 'Partner (1).png', 'Partner (2).png', 'Partner (3).png', 'Partner (4).png', | |
| 'Partner (5).png', 'Partner (6).png', 'Partner (7).png', 'Partner (8).png', | |
| 'Partner (9).png', 'Partner (10).png', 'Partner (11).png', 'Partner (12).png', | |
| 'Partner (13).png', 'Partner (14).png', 'Partner (15).png', 'Partner (16).png', | |
| 'Partner (17).png', 'Partner (18).png', 'Partner (19).png', 'Partner (20).png' | |
| ]; | |
| const baseUrl = 'https://www.shahen-sa.com/assets/images/home/partnerlogos/'; | |
| const container = document.querySelector('.partner-logos-container'); | |
| // Create double set for seamless scrolling | |
| for (let i = 0; i < 2; i++) { | |
| partnerLogos.forEach(logo => { | |
| const logoDiv = document.createElement('div'); | |
| logoDiv.className = 'partner-logo'; | |
| logoDiv.innerHTML = ` | |
| <img src="${baseUrl}${logo}" alt="شريك" class="max-w-full max-h-full object-contain"> | |
| `; | |
| container.appendChild(logoDiv); | |
| }); | |
| } | |
| } | |
| // Form handling for quote request | |
| function handleQuoteRequest(e) { | |
| e.preventDefault(); | |
| const formData = { | |
| name: document.getElementById('name').value, | |
| company: document.getElementById('company').value, | |
| email: document.getElementById('email').value, | |
| phone: document.getElementById('phone').value, | |
| service: document.getElementById('service').value, | |
| details: document.getElementById('details').value | |
| }; | |
| // In a real application, you would send this to a server | |
| console.log('Quote request submitted:', formData); | |
| // Show success message | |
| alert('تم استلام طلبك بنجاح! سيتصل بك فريقنا خلال 24 ساعة عمل.'); | |
| // Reset form | |
| e.target.reset(); | |
| } | |
| // Add form submission handler if form exists | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const quoteForm = document.getElementById('quote-form'); | |
| if (quoteForm) { | |
| quoteForm.addEventListener('submit', handleQuoteRequest); | |
| } | |
| }); | |
| // Mobile menu toggle (for components that might need it) | |
| function toggleMobileMenu() { | |
| const mobileMenu = document.querySelector('.mobile-menu'); | |
| if (mobileMenu) { | |
| mobileMenu.classList.toggle('hidden'); | |
| } | |
| } | |
| // Lazy loading for images | |
| if ('IntersectionObserver' in window) { | |
| const imageObserver = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const img = entry.target; | |
| img.src = img.dataset.src; | |
| img.classList.remove('lazy'); | |
| imageObserver.unobserve(img); | |
| } | |
| }); | |
| }); | |
| document.querySelectorAll('img.lazy').forEach(img => imageObserver.observe(img)); | |
| } |