let lenis; document.addEventListener('DOMContentLoaded', function() { gsap.registerPlugin(ScrollTrigger); lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), smoothWheel: true, smoothTouch: false, touchMultiplier: 2, infinite: false }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); lenis.on('scroll', ScrollTrigger.update); gsap.ticker.lagSmoothing(0); ScrollTrigger.scrollerProxy(document.body, { scrollTop(value) { if (arguments.length) { lenis.scrollTo(value, { immediate: true }); } return lenis.scroll || 0; }, getBoundingClientRect() { return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight }; }, pinType: document.body.style.transform ? "transform" : "fixed" }); ScrollTrigger.defaults({ scroller: document.body }); ScrollTrigger.addEventListener('refresh', () => lenis.resize()); ScrollTrigger.refresh(); let lastScrollTop = 0; const nav = document.querySelector('nav'); lenis.on('scroll', ({ scroll }) => { if (scroll > 100) { nav?.classList.add('scrolled'); } else { nav?.classList.remove('scrolled'); } lastScrollTop = scroll; }); const currentPath = window.location.pathname; const navLinks = document.querySelectorAll('.nav-item-center, .nav-item-left'); navLinks.forEach(navItem => { const link = navItem.querySelector('a'); if (link) { const linkPath = new URL(link.href).pathname; if (linkPath === currentPath || (currentPath === '/' && linkPath === '/')) { navItem.classList.add('active'); } } }); const sidebarLinks = document.querySelectorAll('.sidebar a'); const hash = window.location.hash; if (hash) { sidebarLinks.forEach(link => { if (link.getAttribute('href') === hash) { link.classList.add('active'); } }); } else if (sidebarLinks.length > 0) { sidebarLinks[0].classList.add('active'); } sidebarLinks.forEach(link => { link.addEventListener('click', function() { sidebarLinks.forEach(l => l.classList.remove('active')); this.classList.add('active'); }); }); initParallaxEffects(); initScrollAnimations(); initFloatingElements(); initPageLoadAnimation(); initScrollIndicator(); initStars(); }); function initParallaxEffects() { const heroImage = document.querySelector('.hero-team-image'); if (heroImage) { gsap.to(heroImage, { yPercent: 30, ease: "none", scrollTrigger: { trigger: heroImage.parentElement, start: "top top", end: "bottom top", scrub: 1 } }); } const baseImage = document.querySelector('.overlay-container .base'); if (baseImage) { gsap.to(baseImage, { yPercent: 20, ease: "none", scrollTrigger: { trigger: '.bg', start: "top top", end: "bottom top", scrub: 1.5 } }); } const meetTeamImage = document.querySelector('#meet-our-team'); if (meetTeamImage) { gsap.to(meetTeamImage, { yPercent: 15, ease: "none", scrollTrigger: { trigger: '.team-image-wrapper', start: "top bottom", end: "bottom top", scrub: 1 } }); } } function initScrollAnimations() { const fadeUpElements = document.querySelectorAll('.home-info, .stats-container, .sub-header, .sub-content, .sponsors-container, .hero-image-section, .card, .member-card, .robo-card, .competition-card, .team-section'); fadeUpElements.forEach((element, index) => { gsap.fromTo(element, { opacity: 0, y: 60 }, { opacity: 1, y: 0, duration: 1, ease: "power3.out", scrollTrigger: { trigger: element, start: "top 85%", end: "top 60%", toggleActions: "play none none reverse" } } ); }); const valueCards = document.querySelectorAll('.value-card'); valueCards.forEach((card, index) => { gsap.fromTo(card, { opacity: 0, scale: 0.9, y: 40 }, { opacity: 1, scale: 1, y: 0, duration: 0.8, delay: index * 0.15, ease: "back.out(1.2)", scrollTrigger: { trigger: card, start: "top 85%", toggleActions: "play none none reverse" } } ); }); const statsCards = document.querySelectorAll('.stats-card'); statsCards.forEach((card, index) => { gsap.fromTo(card, { opacity: 0, scale: 0.8, y: 40 }, { opacity: 1, scale: 1, y: 0, duration: 0.8, delay: index * 0.1, ease: "back.out(1.7)", scrollTrigger: { trigger: card, start: "top 85%", toggleActions: "play none none reverse" } } ); }); const headings = document.querySelectorAll('.heading'); headings.forEach(heading => { gsap.fromTo(heading, { opacity: 0, scale: 0.9, y: 30 }, { opacity: 1, scale: 1, y: 0, duration: 0.8, ease: "power2.out", scrollTrigger: { trigger: heading, start: "top 90%", toggleActions: "play none none reverse" } } ); }); const footerText = document.querySelector('.footer-text'); if (footerText) { gsap.fromTo(footerText, { opacity: 0, y: 40 }, { opacity: 1, y: 0, duration: 1.2, delay: 0.5, ease: "power3.out" } ); } } function initMagneticButtons() { const buttons = document.querySelectorAll('.stats-button, .bottom-center-button, #sponsors-more-button, .home-but'); buttons.forEach(button => { button.addEventListener('mouseenter', function(e) { gsap.to(button, { scale: 1.05, duration: 0.3, ease: "power2.out" }); }); button.addEventListener('mouseleave', function(e) { gsap.to(button, { scale: 1, x: 0, y: 0, duration: 0.3, ease: "elastic.out(1, 0.5)" }); }); button.addEventListener('mousemove', function(e) { const rect = button.getBoundingClientRect(); const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; gsap.to(button, { x: x * 0.3, y: y * 0.3, duration: 0.3, ease: "power2.out" }); }); }); } function initFloatingElements() { const cards = document.querySelectorAll('.value-card'); cards.forEach((card, index) => { gsap.to(card, { y: -8, duration: 2.5 + (index % 2) * 0.5, repeat: -1, yoyo: true, ease: "sine.inOut", delay: index * 0.15 }); }); } function initPageLoadAnimation() { gsap.fromTo('body', { opacity: 0 }, { opacity: 1, duration: 0.6, ease: "power2.out" } ); const nav = document.querySelector('nav'); if (nav) { gsap.fromTo(nav, { y: -100, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, delay: 0.2, ease: "power3.out" } ); } const bg = document.querySelector('.bg'); if (bg) { gsap.fromTo(bg, { scale: 1.1, opacity: 0 }, { scale: 1, opacity: 1, duration: 1.5, ease: "power2.out" } ); } } function initCustomCursor() { if (window.innerWidth <= 850) return; const cursor = document.createElement('div'); cursor.className = 'custom-cursor'; document.body.appendChild(cursor); const follower = document.createElement('div'); follower.className = 'custom-cursor-follower'; document.body.appendChild(follower); let mouseX = 0, mouseY = 0; let followerX = 0, followerY = 0; document.addEventListener('mousemove', (e) => { mouseX = e.clientX; mouseY = e.clientY; cursor.style.left = mouseX + 'px'; cursor.style.top = mouseY + 'px'; }); function animateFollower() { followerX += (mouseX - followerX) * 0.1; followerY += (mouseY - followerY) * 0.1; follower.style.left = followerX + 'px'; follower.style.top = followerY + 'px'; requestAnimationFrame(animateFollower); } animateFollower(); const hoverElements = document.querySelectorAll('a, button, .stats-card, .card, .member-card, .robo-card, .sponsors-card'); hoverElements.forEach(el => { el.addEventListener('mouseenter', () => cursor.classList.add('hover')); el.addEventListener('mouseleave', () => cursor.classList.remove('hover')); }); } function initScrollIndicator() { const indicator = document.createElement('div'); indicator.className = 'scroll-indicator'; document.body.appendChild(indicator); lenis.on('scroll', ({ scroll, limit }) => { const progress = (scroll / limit) * 100; indicator.style.width = progress + '%'; }); } function initStars() { const sections = document.querySelectorAll('.home-info, .contributors, .contact, .sponsors, .competitions'); sections.forEach(section => { const starContainer = document.createElement('div'); starContainer.className = 'stars-container'; const sectionHeight = section.offsetHeight; const viewportWidth = window.innerWidth; const numStars = Math.floor((viewportWidth * sectionHeight) / 40000); for (let i = 0; i < numStars; i++) { const star = document.createElement('div'); star.className = 'star'; const size = Math.random() * 3 + 1; const x = Math.random() * 100; const y = Math.random() * 100; const duration = Math.random() * 3 + 2; const delay = Math.random() * 3; star.style.width = size + 'px'; star.style.height = size + 'px'; star.style.left = x + '%'; star.style.top = y + '%'; star.style.setProperty('--duration', duration + 's'); star.style.setProperty('--delay', delay + 's'); starContainer.appendChild(star); } section.appendChild(starContainer); }); }