1document.addEventListener('DOMContentLoaded', function () { 2 // Cache DOM elements 3 const popup = document.getElementById('eventPopup'); 4 const closeBtn = document.querySelector('.close-popup'); 5 const knowMoreBtns = document.querySelectorAll('.know-more-btn'); 6 const popupName = document.getElementById('popupName'); 7 const popupDescription = document.getElementById('popupDescription'); 8 const popupDateFrom = document.getElementById('popupDateFrom'); 9 const popupDateTo = document.getElementById('popupDateTo'); 10 const popupLocation = document.getElementById('popupLocation'); 11 12 const timeItems = document.querySelectorAll('.time-item'); 13 const mainImg = document.getElementById('main-time-line-img'); // Image remains static 14 const timelineYear = document.getElementById('timeline-year'); 15 const timelineDescription = document.getElementById('timeline-description'); 16 17 let isAnimating = false; 18 19 // Function to update the timeline content 20 function updateTimelineContent(item) { 21 if (isAnimating || item.classList.contains('active')) return; 22 isAnimating = true; 23 24 // Remove active class from all items 25 timeItems.forEach(timeItem => timeItem.classList.remove('active')); 26 27 // Add active class to the clicked item 28 item.classList.add('active'); 29 const year = item.getAttribute('data-year'); 30 const description = item.getAttribute('data-description'); 31 32 const tl = gsap.timeline({ onComplete: () => { isAnimating = false; } }); 33 34 // Animate the content transition (year and description only) 35 tl.to([timelineYear, timelineDescription], { opacity: 0, y: -20, duration: 0.3, stagger: 0.1 }) 36 .call(() => { 37 // Update content 38 timelineYear.textContent = year; 39 timelineDescription.innerHTML = description; 40 }) 41 .to([timelineYear, timelineDescription], { opacity: 1, y: 0, duration: 0.5, stagger: 0.1 }); 42 } 43 44 // Function to load the default active item on page load 45 function loadDefaultActiveItem() { 46 const defaultItem = timeItems[0]; // Select the very first item 47 if (defaultItem) { 48 defaultItem.classList.add('active'); // Mark it as active 49 updateTimelineContent(defaultItem); // Load its content 50 } 51 } 52 53 // Event listeners for timeline items 54 timeItems.forEach(item => { 55 // Click to update timeline content 56 item.addEventListener('click', () => updateTimelineContent(item)); 57 58 // Hover effect for timeline items 59 item.addEventListener('mouseenter', () => { 60 if (!item.classList.contains('active')) { 61 gsap.to(item, { scale: 1.05, duration: 0.3, ease: 'power2.out' }); 62 } 63 }); 64 65 item.addEventListener('mouseleave', () => { 66 if (!item.classList.contains('active')) { 67 gsap.to(item, { scale: 1, duration: 0.3, ease: 'power2.out' }); 68 } 69 }); 70 }); 71 72 // Event listener for "Know More" buttons 73 knowMoreBtns.forEach(btn => { 74 btn.addEventListener('click', function () { 75 popupName.textContent = this.dataset.name; 76 popupDescription.textContent = this.dataset.description; 77 popupDateFrom.textContent = this.dataset.datefrom; 78 popupDateTo.textContent = this.dataset.dateto || 'N/A'; 79 popupLocation.textContent = this.dataset.location || 'N/A'; 80 popup.classList.add('visible'); 81 }); 82 }); 83 84 // Close popup functionality 85 closeBtn.addEventListener('click', function () { 86 popup.classList.remove('visible'); 87 }); 88 89 popup.addEventListener('click', function (e) { 90 if (e.target === popup) { 91 popup.classList.remove('visible'); 92 } 93 }); 94 95 // Load the default active item 96 loadDefaultActiveItem(); 97});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.